Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Определение размера файла в Delphi

Автор: kipus
Дата сообщения: 25.08.2003 07:07
Надо определить размер файла в Delphi при условии, что его размер в ьайтах больше возможного для Integer размера.
Например, образ DVD (5 Гб)
У меня - 14 Гб файл.
Автор: ShIvADeSt
Дата сообщения: 25.08.2003 08:21
Попробуй
The GetFileSize function retrieves the size, in bytes, of the specified file.

DWORD GetFileSize(

HANDLE hFile, // handle of file to get size of
LPDWORD lpFileSizeHigh // address of high-order word for file size
);
и в качестве типа не интегер, а что-то типа LongInt или INt64. Ты наверное используешь FileSize, а там в самом деле маловато выделено под результат. В таких случаях юзай АПИ функции. Для получения Хэндла используй CreateFile с параметрами.
Автор: kipus
Дата сообщения: 25.08.2003 13:41
Спасибо, попробую.
А какой аналог Seek в WinAPI?
Автор: mastervigo
Дата сообщения: 03.09.2003 05:25
kipus
по-моему, в RxLibrary функция поддерживает больший тип чем Integer,
иначе поработай со строковым типом. тогда уже точно любая цифра поместится
Автор: ShIvADeSt
Дата сообщения: 03.09.2003 07:41
mastervigo

Цитата:
иначе поработай со строковым типом. тогда уже точно любая цифра поместится

ты сам хоть понял что сказал? . Какая функция при определении численного значения будет помещать его в строку? Она это значение должна засунуть в переменную а вот здесь и всплывает уже решенная выше проблема. Использовать АПИ и больший тип данных.
Автор: UncoNNecteD
Дата сообщения: 03.09.2003 19:32
ShIvADeSt

Цитата:
DWORD GetFileSize(.....

DWORD не больше Integer'а.
Кстати я вообще не видел файлов больше 2 Ггб
Автор: naPmu3aH
Дата сообщения: 03.09.2003 20:27

Цитата:
Кстати я вообще не видел файлов больше 2 Ггб

Это ведь не значит что их не бывает.
Или смени операционную систему!
Автор: ShIvADeSt
Дата сообщения: 03.09.2003 23:41
UncoNNecteD

Цитата:
DWORD не больше Integer'а.

а согласно описанию

Цитата:

DWORD = LongWord;
Integer –2147483648..2147483647 signed 32-bit
Cardinal 0..4294967295 unsigned 32-bit

Word 0..65535 unsigned 16-bit
Longword 0..4294967295 unsigned 32-bit

Он может и не больше, но однако размер передает точнее. Так как я не видел файл с отрицательным размером . А вообще начиная с D4 появился Int64. Он очень большой.
И начет боьших файлов. Там же посте приведен пример образа DVD с его размером.
Автор: kipus
Дата сообщения: 04.09.2003 07:00
Я не очень разбираюсь в WinAPI. Помогите, pls. Как получить хэндл файла? Почитал про функцию, но так и не понял все. Хотелось бы пример увидеть.
Автор: ShIvADeSt
Дата сообщения: 04.09.2003 07:49
kipus ты вначале напиши какую функцию использовал.
Автор: kipus
Дата сообщения: 04.09.2003 08:00
ShIvADeSt
CreateFile
Автор: ShIvADeSt
Дата сообщения: 04.09.2003 23:53
kipus

procedure TForm1.Button1Click(Sender: TObject);
var
hFile :THandle;
begin
hFile:=CreateFile('C:\Temp\qq.log',GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,0);
CloseHandle(hFile);
end;
между первой и второй строкой делай запись\чтение из файла. Только флаги нужные подбирай. Так как у меня файл всегда обнуляется (ну флаг у меня такой ).
Автор: kipus
Дата сообщения: 05.09.2003 06:09
ShIvADeSt
Спасибо. Последний вопрос:
Я читаю и пишу файл коммандами BlockRead и BlockWrite соответственно. Они намного быстрее обычного Read и Write. Но не нашел аналогов в API. После открытия таким способом можно стандартные функции Delphi использовать?
Автор: ShIvADeSt
Дата сообщения: 05.09.2003 06:17
kipus

Цитата:
Я читаю и пишу файл коммандами BlockRead и BlockWrite соответственно.

с открытым таким способом файлом нальзя использовать эти процедуры. Вот одна из тех которые можно Сам я этим не занимался поэтому примера нет. Аналогичные ищи по Хэлпу.


Цитата:
The ReadFile function reads data from a file, starting at the position indicated by the file pointer. After the read operation has been completed, the file pointer is adjusted by the number of bytes actually read, unless the file handle is created with the overlapped attribute. If the file handle is created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the read operation.

BOOL ReadFile(

HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // address of buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // address of number of bytes read
LPOVERLAPPED lpOverlapped // address of structure for data
);

Может кто поможет
Автор: UncoNNecteD
Дата сообщения: 05.09.2003 06:52
Да я не говорю что не бывает больше файлов.
Просто если функция возвращает что то - как то, то пофиг куда это записывать, нужно юзать native type возвращаемого значения.
Автор: ShIvADeSt
Дата сообщения: 05.09.2003 06:58
UncoNNecteD

Цитата:
Просто если функция возвращает что то - как то, то пофиг куда это записывать, нужно юзать native type возвращаемого значения.

Согласен, но иногда функиця достаточно устарела. Например я очень радовался когда у меня StrToInt не хотела переводить достаточно длинное число. А по старинке Val все на ура. Я это к тому, что прежде чем использовать native types, надо вначале посмотреть а каков у них размер, чтобы потом не пришлось перекомпилить прогу изза того что размер файла меньше нуля.
Автор: wyrd
Дата сообщения: 05.09.2003 22:21

Цитата:
Я читаю и пишу файл коммандами BlockRead и BlockWrite соответственно. Они намного быстрее обычного Read и Write. Но не нашел аналогов в API. После открытия таким способом можно стандартные функции Delphi использовать?

Вместо вызовов CreateFile, ReadFile, WriteFile... etc ты можешь использовать аналогичные функции в Delphi FileOpen, FileRead, FileWrite... etc.
Эти функции WinAPI и Delphi RTL можно использовать взаимозаменяемо.
Автор: UncoNNecteD
Дата сообщения: 08.09.2003 17:31
DWORD'а все равно не хватит на 5 Ггб.
Че делать то?
Автор: wyrd
Дата сообщения: 08.09.2003 21:08

Цитата:
DWORD'а все равно не хватит на 5 Ггб.
Че делать то?

Функция FileSeek может работать со смещением типа Int64.
Автор: Pupsik
Дата сообщения: 09.09.2003 05:45
Да, в WinAPI есть такая фукция:
The SetFilePointer function moves the file pointer of an open file.

DWORD SetFilePointer(
HANDLE hFile, // handle of file
LONG lDistanceToMove, // number of bytes to move file pointer
PLONG lpDistanceToMoveHigh, // address of high-order word of distance to move
DWORD dwMoveMethod // how to move
);
В ней куда передвинуть указатель файла определяется аж двумя LONGами:
lDistanceToMove и lpDistanceToMoveHigh (указатель на LONG)
Для определения размера пишешь:
LoLong := SetFilePointer(Handle, 0, @HiLong, FILE_END);
т.е. указатель встает на конец файла и возвращает (цитирую хелп):

If the SetFilePointer function succeeds, the return value is the low-order doubleword of the new file pointer, and if lpDistanceToMoveHigh is not NULL, the function puts the high-order doubleword of the new file pointer into the LONG pointed to by that parameter


Добавлено
Хотя, есть и

The GetFileSize function retrieves the size, in bytes, of the specified file.
DWORD GetFileSize(
HANDLE hFile, // handle of file to get size of
LPDWORD lpFileSizeHigh // address of high-order word for file size
);
If the function succeeds, the return value is the low-order doubleword of the file size, and, if lpFileSizeHigh is non-NULL, the function puts the high-order doubleword of the file size into the variable pointed to by that parameter.

тоже самое, только вид сбоку...
Автор: BugFixer
Дата сообщения: 09.09.2003 13:09
UncoNNecteD

Цитата:
DWORD'а все равно не хватит на 5 Ггб.
Че делать то?


Читать документацию!

Цитата:

GetFileSizeEx
The GetFileSizeEx function retrieves the size of a specified file.

BOOL GetFileSizeEx(
HANDLE hFile, // handle to file
PLARGE_INTEGER lpFileSize // file size
);
Parameters
hFile
[in] Handle to the file whose size is to be returned. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.
lpFileSize
[out] Pointer to a LARGE_INTEGER structure that receives the file size.

А LARGE_INTEGER, как известно,

Цитата:

The LARGE_INTEGER structure is used to represent a 64-bit signed integer value.

typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;


Хотя это практически то же, что и было описано ранее, но вдруг Вас устокоит?
Автор: wyrd
Дата сообщения: 09.09.2003 22:11
И в завершении дискуссии хочу добавить, что можно использовать обычный TFileStream.
Автор: ShIvADeSt
Дата сообщения: 15.09.2003 00:38
Pupsik
Я вот только отдного не догнал ты че меня передразниваешь. Я то же самое цитировал, а ты это с умным видом дополнял.
Автор: Pupsik
Дата сообщения: 15.09.2003 05:09
ShIvADeSt
Успокойся.
Автор: UncoNNecteD
Дата сообщения: 15.09.2003 07:46
Коллеги не ссорьтесъ
Автор: kipus
Дата сообщения: 16.09.2003 06:50
Всем спасибо! Нашел наиболее короткий и подходящий мне способ.
Если кого-то интересует:

Цитата:
Function FileSize64(FileName:string):int64;
var ts:TSearchRec;
begin
if FindFirst(FileName, faAnyFile, ts)=0 then
begin
Result:=ts.FindData.nFileSizeHigh*4294967296+ts.FindData.nFileSizeLow;
Findclose(ts);
end
end;

Автор: cybermake
Дата сообщения: 12.02.2011 15:00
А почему так нельзя?
Помоему так проще:

i: Int64;

stream := TFileStream.Create(FilePath, fmOpenRead);
i := stream.Size;

и диапазон Int64
-2^63..2^63-1    signed 64-bit

я так понял этого вам хватит чтобы измерить файл размером до 2097152 терабайт

Вот кстати если комк интресно парсер написал на делфи, он постоянно файлы юзайет
http://cybermake.ru/view/view_web_parser.php
Автор: Eternal_Shield
Дата сообщения: 12.02.2011 16:39
kipus
М-да, клинический случай. Вот, пользуйтесь на здоровье, а тот бред с поиском и умножением выкиньте подальше...чтобы никто больше не видел.


Код:
function FileSize(const AFileName: String): UInt64; inline;
var
hFile: THandle;
begin
Result := 0;

hFile := FileOpen(AFileName, FILE_SHARE_READ);
if hFile = INVALID_HANDLE_VALUE then Exit;

Int64Rec(Result).Lo := GetFileSize(hFile, @Int64Rec(Result).Hi);
CloseHandle(hFile);
end;

Страницы: 1

Предыдущая тема: Shareware protection


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.