Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2014.04.27;
Скачать: CL | DM;

Вниз

странности FindFirst   Найти похожие ветки 

 
wp2   (2011-12-13 16:45) [0]

задача была найти файлы типа фывфыва001фываывфа
фвафыва002фывафыва
фывафыва003фвыафыва
фывафыва004фывафыва
и т.д.

и соответственно их переименовать по нужному принципу

function AddZero(a: Integer): String;//добавление
передних нулей
var i: Integer;
   s: String;
begin
   s := IntToStr(a);
   for i := 1 to 3 - Length(s) do
   s := "0" + s;
   AddZero := s;  
end;



//основной код
for i := 1 to 118 do
 begin
   Zero := AddZero(i);
   R := FindFirst(Dir + "*" + Zero + "*", faAnyFile, Find);
  //обработка файла
 FindClose(Find);
 end;


Всё работает, но...
вы не поверите, то файлы 004, 014 не находит! Точнее находит но не их! А какой-нибудь 186, например. Переменная R = 0.


 
wp2   (2011-12-13 17:06) [1]

^ не находит файлы с четверками


 
Медвежонок Пятачок ©   (2011-12-13 17:30) [2]

Если r=0 значит находит


 
Dimka Maslov ©   (2011-12-13 18:26) [3]

1. Вместо AddZero для подобных вещей надо пользоваться Format
2. Странно что находит 186 при цикле до 118
3. Раз находит, но не их, значит есть другие файлы с такой маской.
4. Раз находит, но не их, значит надо вызывать FindNext, чтобы найти их.


 
wp2   (2011-12-13 18:34) [4]

попробовал вот так:

for i := 4 to 118 do
 begin
   Zero := AddZero(i);
   R := FindFirst(Dir + "*004*", faAnyFile, Find);


всё равно :)


 
wp2   (2011-12-13 18:38) [5]

добавил строку if Pos("004", Find.Name) = 0 then FindNext(Find);

еще что-то левое нашло)

может это так винда у меня глючит...


 
wp2   (2011-12-13 18:45) [6]

только что заметил, что в Find.FindData.cAlternateFileName правильное найденное имя файла, только в формате 8.3


 
sniknik ©   (2011-12-13 19:06) [7]

программа консольная что ли?


 
wp2   (2011-12-13 19:13) [8]

нет

а какое это имеет значение?


 
sniknik ©   (2011-12-13 19:22) [9]

короткие имена это наследство от дос, близко к консоли.
просто мысль/предположение, а почему оно может искать в коротких именах?


 
wp2   (2011-12-13 20:10) [10]

ну... тут прикол в самой WinAPI структуре TWin32FindData. В неё записывается как длинное имя, так и короткое.

Вот длинное, не то что надо, а короткое норм, только в сжатом формате :(

по сабжу: честно говоря уже начинаю сдаваться, перепробовал всё что мог и придумал. Даже искал с помощью WinAPI функций. Та же проблема.

думал, может файловая система повреждена. Но вроде всё норм.
Думал, может эти тестовые файлы фвафыва002фывафыва и т.д. криво созданы?
но нет, перепробовал разными способами их создавать.

ХЗ!


 
Дмитрий Белькевич   (2011-12-13 20:26) [11]

Дай соответствующую команду dir из командной строки. Может чем-то поможет.


 
MBo ©   (2011-12-13 20:43) [12]

файл "фывфыва014фываывфа" получает короткое имя вроде "фывф~001"

Стоит попробовать FindFirstFileEx и с infolevel разобраться (у меня не открывается описание его значений)


 
sniknik ©   (2011-12-13 21:18) [13]

странно, проверил, не заполняется у меня cAlternateFileName ... не находится по короткому имени поэтому значит... винда XP. D7.


 
sniknik ©   (2011-12-13 21:31) [14]

а, по моему понял/вспомнил на ntfs подобного нет. или нет...?


 
wp2   (2011-12-13 23:31) [15]

значит так:
если почему именно тот случай не работал, так и не понял.
Для примера взял несколько другой пример, например q001q q002q и т.д.

работает.


 
Inovet ©   (2011-12-14 00:07) [16]

> [15] wp2   (13.12.11 23:31)
> Для примера взял несколько другой пример, например

"Для примера, например, возмём такой пример." из ответов на вступительных экзаменах (журнал Квант).


 
Плохиш ©   (2011-12-14 00:48) [17]


> wp2   (13.12.11 16:45)  

Вот эти функции попробуй

{$WARN SYMBOL_PLATFORM OFF}
unit SysUtilsW;

interface

uses
   Windows;
   
type
 TSearchRecW = record
   Time: Integer;
   Size: Integer;
   Attr: Integer;
   Name: WideString;
   ExcludeAttr: Integer;
   FindHandle: THandle  platform;
   FindData: TWin32FindDataW  platform;
 end;

 //  From SysUtils
 LongRec = packed record
   case Integer of
     0: (Lo, Hi: Word);
     1: (Words: array [0..1] of Word);
     2: (Bytes: array [0..3] of Byte);
 end;

const
{ File attribute constants }

 faReadOnly  = $00000001 platform;
 faHidden    = $00000002 platform;
 faSysFile   = $00000004 platform;
 faVolumeID  = $00000008 platform;
 faDirectory = $00000010;
 faArchive   = $00000020 platform;
 faSymLink   = $00000040 platform;
 faAnyFile   = $0000003F;

procedure FindCloseW(var F: TSearchRecW);
function FindFirstW(const Path: WideString; Attr: Integer; var  F: TSearchRecW): Integer;
function FindNextW(var F: TSearchRecW): Integer;
function WideCharToChar(const WCh: WideChar): String;
function WideStringToTranslit(const WString: WideString): String;

implementation

function FindMatchingFileW(var F: TSearchRecW): Integer;
var
 LocalFileTime: TFileTime;
begin
 with F do
 begin
   while FindData.dwFileAttributes and ExcludeAttr <> 0 do
     if not FindNextFileW(FindHandle, FindData) then
     begin
       Result := GetLastError;
       Exit;
     end;
   FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
   FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo);
   Size := FindData.nFileSizeLow;
   Attr := FindData.dwFileAttributes;
   Name :=  FindData.cFileName;
 end;
 Result := 0;
end;

procedure FindCloseW(var F: TSearchRecW);
begin
 if F.FindHandle <> INVALID_HANDLE_VALUE then
 begin
   Windows.FindClose(F.FindHandle);
   F.FindHandle := INVALID_HANDLE_VALUE;
 end;
end;

function FindFirstW(const Path: WideString; Attr: Integer;
 var  F: TSearchRecW): Integer;
const
 faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
begin
 F.ExcludeAttr := not Attr and faSpecial;
 F.FindHandle := FindFirstFileW(PWideChar(Path), F.FindData);
 if F.FindHandle <> INVALID_HANDLE_VALUE then
 begin
   Result := FindMatchingFileW(F);
   if Result <> 0 then FindCloseW(F);
 end else
   Result := GetLastError;
end;

function FindNextW(var F: TSearchRecW): Integer;
begin
 if FindNextFileW(F.FindHandle, F.FindData) then
   Result := FindMatchingFileW(F) else
   Result := GetLastError;
end;


 
sniknik ©   (2011-12-14 01:34) [18]

> почему именно тот случай не работал, так и не понял.
см.
MBo ©   (13.12.11 20:43) [12]


 
Германн ©   (2011-12-14 01:35) [19]


> Плохиш ©   (14.12.11 00:48) [17]

Что-то ты сегодня лишком добрый :)


 
sniknik ©   (2011-12-14 01:40) [20]

+ сделай пример с функциями -GetShortFileName/Path, GetLongFileName/Path


 
wp2   (2011-12-14 02:15) [21]


> > [15] wp2   (13.12.11 23:31)> Для примера взял несколько
> другой пример, например "Для примера, например, возмём такой
> пример." из ответов на вступительных экзаменах (журнал Квант).
>

у меня есть проблема, когда я программирую, то не могу и двух слов связать. Мне даже написать на листе бумаги что-то сложно. Потом разобрать не могу)


 
wp2   (2011-12-14 02:18) [22]


> Плохиш ©   (14.12.11 00:48) [17]

это ж всё для Юникода...


 
han_malign   (2011-12-14 17:47) [23]


> это ж всё для Юникода...

- угу, который работает без ограничения MAX_PATH...


 
Плохиш ©   (2011-12-14 19:08) [24]


> Германн ©   (14.12.11 01:35) [19]

Судя по [22] пациент безнадёжен :-)


 
wp2   (2011-12-14 19:51) [25]


> MBo ©   (13.12.11 20:43) [12]
> файл "фывфыва014фываывфа" получает короткое имя вроде "фывф~001"Стоит
> попробовать FindFirstFileEx и с infolevel разобраться (у
> меня не открывается описание его значений)

с параметром FindExInfoStandard всё так же само. С параметром FindExInfoMaxInfoLevel вообще ничего не находит.


 
MBo ©   (2011-12-14 20:10) [26]

а FindExInfoBasic ?


 
wp2   (2011-12-14 20:12) [27]

var Se: WideString;
Search: PWideChar;
R: Integer;
FindData: WIN32_FIND_DATAW;

begin

Zero := "004";
Se := Dir + "*" + Zero + "*";
Search := PWideChar(Se);

R := FindFirstFileW(Search, FindData);

проблема не решилась.


 
wp2   (2011-12-14 20:46) [28]


> MBo ©   (14.12.11 20:10) [26]
> а FindExInfoBasic ?

В Delphi 7 нет такого.

Windows.pas
_FINDEX_INFO_LEVELS = (FindExInfoStandard, FindExInfoMaxInfoLevel);


 
MBo ©   (2011-12-14 21:01) [29]

>В Delphi 7 нет такого.
У, оно вообще с Win7 только введено, тогда отбой."

Видимо, остаётся то, что давно сказали:
>4. Раз находит, но не их, значит надо вызывать FindNext, чтобы найти их.


 
wp2   (2011-12-14 21:11) [30]

у меня ж задача обрабатывать файлы типа asdfasdf001asdfasdf
то есть, они должны идти по очереди (там есть нюансы в обработке). Я конечно могу использовать FindNext, но я ж не знаю, какой оно файл найдёт. Придётся присать огромный case...
Ясно видно, что маска *число* не всегда работает.

#include<windows.h>
#include<stdio.h>

void main(void)
{
WIN32_FIND_DATA FindData;
HANDLE h;
char *name, *Search;

name = (char *)malloc(100);
Search = (char *)malloc(100);

printf("path = "); scanf("%s", name);

strcpy(Search, "*004*");

h = FindFirstFile(strcat(name, Search), &FindData);

printf("h = %i\n", h);
printf("%s", FindData.cFileName);
}

выводит:

path = C:\a\
h=1319168
asdfasdf185asdfasdf


пока отбой. Будем считать проблему не решенной.


 
wp2   (2011-12-14 21:18) [31]

[I]>значит надо вызывать FindNext, чтобы найти их.[/I]
можно конечно, если не тот результат, то зациклить FindNext до выдачи нужного. Но, у меня 200 файлов, если я каждый из них буду так искать, то количество поисков будет максимум 200х200. Весело :)


 
MBo ©   (2011-12-14 21:23) [32]

>если я каждый из них буду так искать, то количество поисков будет максимум 200х200.

Другой путь - перебрать все файлы, переименовать каждый, подлежащий переименованию, как надо


 
wp2   (2011-12-14 21:48) [33]

была и такая идея)
тогда уже bat-файл лучше написать :)

эх, если бы кто-то сам у себя на компе попробовал... Исходник на С языке я дал. Осталось только написать прогу, создающую файлы asdfasdf001asdfasdf...asdfasdf238asdfasdf


 
sniknik ©   (2011-12-14 22:35) [34]

> эх, если бы кто-то сам у себя на компе попробовал...
sniknik ©   (13.12.11 21:18) [13]
> странно, проверил, не заполняется у меня cAlternateFileName ... не находится по короткому имени поэтому значит... винда XP. D7.
sniknik ©   (13.12.11 21:31) [14]
> а, по моему понял/вспомнил на ntfs подобного нет. или нет...?


 
wp2   (2011-12-14 22:37) [35]

всё таки Винда виновата?

у меня win2003server (так, от нечего делать поставил).


 
Anatoly Podgoretsky ©   (2011-12-14 22:37) [36]


>  Но, у меня 200 файлов, если я каждый из них буду так искать,
>  то количество поисков будет максимум 200х200. Весело :)

А умные загоняют их в сортированый список, например StringList, и 200х200 может превратиться в 200


 
Anatoly Podgoretsky ©   (2011-12-14 22:38) [37]


> Исходник на С языке я дал.

Cи обсуждаем в Общей, а здесь Дельфи.


 
wp2   (2011-12-14 23:19) [38]


> А умные загоняют их в сортированый список, например StringList,
>  и 200х200 может превратиться в 200

а кстати, хорошая идея.

где ж ты раньше был :)


 
wp2   (2011-12-15 00:40) [39]

всем спасибо (особенно Anatoly Podgoretsky). Сделал через TStringList.


 
Германн ©   (2011-12-15 01:32) [40]


> wp2   (15.12.11 00:40) [39]
>
> всем спасибо (особенно Anatoly Podgoretsky). Сделал через
> TStringList.
>

Не знаю "к селу или к городу" моё высказывание. Но ещё во времена Turbo Pascal"я  понял, что нельзя внутри блока FindFirst-FindNext-FindClose изменять файлы. Файлы "перезаписываются" и работа FindNext сбивается.



Страницы: 1 2 вся ветка

Текущий архив: 2014.04.27;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.006 c
3-1297252094
Гость
2011-02-09 14:48
2014.04.27
Подскажите как получить таблицу-матрицу запросом в MSSQL


2-1374245465
loser
2013-07-19 18:51
2014.04.27
Вызов функции из DLL в методе объекта


15-1383645741
Sign
2013-11-05 14:02
2014.04.27
COM объект на .NET вызов из Delphi


2-1374264972
Vasa777
2013-07-20 00:16
2014.04.27
pbyte


15-1383227337
брат Птибурдукова
2013-10-31 17:48
2014.04.27
"Сейчас позднее, чем ты думаешь"