Page 1 of 1

Проверка наличия файла

Posted: 28.04.2008 17:32
by Vizit0r
Захотелось мне на досуге проверить наличие файла. Зачем, для чего - неважно.
Полез я в дэльфы, посмотреть как там это реализовано. В итоге с простой, казалось бы функции FileExists скатился до FindFirstFile

на выходе получил такого вот адаптированного монстрика:

Code: Select all

Program test; 
type
  TFileTime= record
    dwLowDateTime: WORD;
    dwHighDateTime: WORD;
end;
   FIND_DATA = record
    dwFileAttributes: WORD;
    ftCreationTime: TFileTime;
    ftLastAccessTime: TFileTime;
    ftLastWriteTime: TFileTime;
    nFileSizeHigh: WORD;
    nFileSizeLow: WORD;
    dwReserved0: WORD;
    dwReserved1: WORD;
end;

function FindFirstFile : THandle; external '[email protected]';
begin
FindFirstFile('c:\s2.txt',FIND_DATA);
End.
какие только параметры я ему не кормил...
в ответ неизменно получаю
18:34:01 []: Compiler: [Error] (test at 22:xx): Invalid number of parameters

Сдается мне, что должно быть что-то попроще...
Т.е. если файл есть, скрипт делает то-то, если нет - то делает другое...
и естественно без окон ошибок, выбиваемых самим стелсом.
Посоветуйте что-то плиз

Re: Проверка наличия файла

Posted: 28.04.2008 17:46
by CFA
имхо импортировать надо как то так,

Code: Select all

function FindFirstFile(lpFileName : pChar; lpFindFileData : ^FIND_DATA) : THandle; external '[email protected]';
но в связи с тем, что pascalScript указатели не поддерживает, сомневаюсь, что получится так.
стоит попробовать так -

Code: Select all

function FindFirstFile(lpFileName : pChar; var lpFindFileData : FIND_DATA) : THandle; external '[email protected] stdcall'; 
но опять таки, уверенности, что получится нет, пробовать самому лень +)) ну и про stdcall забывать не стоит

Re: Проверка наличия файла

Posted: 28.04.2008 17:53
by CFA
А что касаемо "попроще" то наличие файла можно проверять с помощью, например, TStringList -

Code: Select all

function fileExist(fname : string) : boolean;
var ls : TStringList;
begin
    ls : = TStringList.Create();
    try
        ls.loadFromFile(fname);
        // если нет ошибки, выполнится этот код
        result := true;
    except
        // если ошибка, выполнится этот код
        result := false;
    end;
    ls.free()
end;
хотя правильней будет использовать TFileStream, тк не понятно как поведет себя TStringList на бинарных данных

Posted: 28.04.2008 19:15
by Vizit0r
CFA
насчет try...except с самого начала думал, но чем-то оно мне не понравилось и пошел дальше.
надо все ж вернуться назад и попробовать сие.

спасибо


А насчет того, что при импорте забыл указать параметры - этоя канеш тупанул

Posted: 29.04.2008 14:56
by Vizit0r

Code: Select all

Program Spirit; 

{$Include 'all.inc'} 
type
  TFileTime= record
    dwLowDateTime: WORD;
    dwHighDateTime: WORD;
end;
   FIND_DATA = record
    dwFileAttributes: WORD;
    ftCreationTime: TFileTime;
    ftLastAccessTime: TFileTime;
    ftLastWriteTime: TFileTime;
    nFileSizeHigh: WORD;
    nFileSizeLow: WORD;
    dwReserved0: WORD;
    dwReserved1: WORD;
end;

function FindFirstFile(lpFileName : pChar; var lpFindFileData : FIND_DATA) : THandle; external '[email protected]';
var
a:FIND_DATA;
begin
if FindFirstFile('c:\s2.txt',a) <> WORD(-1) then UOSay('11111');

End.
в ответ на это, стелс просто закрывается (11111 - не говорит)
вобщем, порадовал. Он типа отрабатывает, но просто вылетает без всяких ошибок:)

Posted: 29.04.2008 15:02
by CFA
stdcall добавь

Posted: 29.04.2008 15:24
by CFA
я таки не поленился и проверил все сам

Code: Select all

Program Spirit; 

type 
	DWORD = cardinal;
  
	TFileTime= record 
		dwLowDateTime: DWORD; 
		dwHighDateTime: DWORD; 
	end; 

	FIND_DATA = record 
		dwFileAttributes	: DWORD; 
		ftCreationTime		: TFileTime; 
		ftLastAccessTime	: TFileTime; 
		ftLastWriteTime		: TFileTime; 
		nFileSizeHigh		: DWORD; 
		nFileSizeLow		: DWORD; 
		dwOID				: DWORD; 
		cFileName			: array[0..259] of char;
	end; 

function FindFirstFile(lpFileName : pChar; var lpFindFileData : FIND_DATA) : THandle; external '[email protected] stdcall'; 

var 
	a:FIND_DATA; 
begin 
	addToSystemJournal(intToStr(FindFirstFile('c:\s2.txt', a)));
End.


в таком виде все работает. в варианте твоем структура FIND_DATA была
несколько отличной от той, что в msdn. паскалевкий word - 16 битный, а DWORD - 32, в итоге она получалась короче, и напрочь отсутсвовал cFileName, что и приводило к плачевным последствиям. ну и stdcall тоже немаловажен.

Posted: 01.05.2008 7:37
by Vizit0r
мне изначально стелс в.ыругался на dword. Я ж не просто так его урезал до простого ворда. Не додумался кардиналом его обьявить...

Спасибо.

Posted: 01.05.2008 8:41
by Vizit0r
кстати,
cAlternateFileName: array[0..13] of AnsiChar;

не используется получается?


9:48:04 [Tester]: 1525032
9:48:11 [Tester]: 1516120

первый результат - без cAlternateFileName, второй с ним :)
впрочем, хрен с ним - работает без него и все.

Posted: 01.05.2008 8:53
by CFA
Vizit0r wrote:кстати,
cAlternateFileName: array[0..13] of AnsiChar;
в msdn'е от 2008 студии такого не наблюдаецо, равно как и DWORD dwReserved0; DWORD dwReserved1; поэтому я и не писал их. Это думаю было актуально для win95/98/me

Posted: 01.05.2008 11:14
by Edred
Когда дискуссия будет завершена, перенесу топик в FAQ.