Форум: "KOL";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];
ВнизОшибка в FileSize Найти похожие ветки
← →
MTsv DN © (2006-12-21 22:55) [0]Вот тестовый проект:
program test;
uses KOL;
var
Form, Edit, Button : PControl;
procedure OnClick_( Dummy : Pointer; Sender: PControl);
var
F : File;
Buf : array [0..511] of Byte;
i : integer;
begin
Button.Enabled := false;
Assign(F, "tmp.tmp");
Rewrite(F, 1);
for i := 0 to 1000 do
BlockWrite(F, Buf, 512);
CloseFile(F);
Button.Enabled := true;
if FileSize("tmp.tmp") < 1000000 then
Edit.Text := "tmp.tmp";
end;
begin
Form := NewForm(nil, "").SetSize(200, 80);
Form.CenterOnParent;
Edit := NewEditBox(Form, []).SetAlign(caTop);
Button := NewButton(Form, "Click").SetAlign(caBottom);
Button.OnClick := TOnEvent(MakeMethod(nil, @OnClick_));
Run(Form);
end.
Результат этой строчки в KOL.PAS:Result := {$IFDEF _D2orD3} FD.nFileSizeLow
{$ELSE} PInt64( @ FD.nFileSizeLow )^ {$ENDIF};
Result := 72339446972273152
Почему бы не вернуться к коду:function FileSize( const Path: KOLString ) : {$IFDEF _D2orD3} Integer {$ELSE} Int64 {$ENDIF};
var FD : TFindFileData;
HiSize : {$IFDEF _D2orD3} Integer {$ELSE} Int64 {$ENDIF};
begin
Result := 0;
if not Find_First( Path, FD ) then exit;
Result := FD.nFileSizeLow;
{$IFNDEF _D2orD3}
if ((FD.nFileSizeLow and $80000000) <> 0) or
(FD.nFileSizeHigh <> 0) then
begin
HiSize := FD.nFileSizeHigh * MAXDWORD;
Result := HiSize + FD.nFileSizeLow;
end;
{$ENDIF}
Find_Close( FD );
end;
Он также учитывает файлы БОЛЬШИХ РАЗМЕРОВ.
← →
Galkov © (2006-12-22 00:21) [1]Конечно бага... У Билла тоже - ума палата. Это надо же было старшее слово раньше поставить...
Хитрые умножения против 2-х mov-ов это перебор, конечно...
Что-нибудь такого типа надо:type T = record L,H:DWORD end;
..........
T(Result).L := FD.nFileSizeLow;
T(Result).H := FD.nFileSizeHigh;
← →
Galkov © (2006-12-22 09:02) [2]
> Он также учитывает файлы БОЛЬШИХ РАЗМЕРОВ.
Учитывает. Только правильно ли :)))
← →
MTsv DN © (2006-12-22 10:00) [3]> Учитывает. Только правильно ли :)))
Понял что намек, но не понял на что :)
Вот из MSDN про это:nFileSizeHigh
Specifies the high-order DWORD value of the file size, in bytes. This value is zero unless the file size is greater than MAXDWORD. The size of the file is equal to (nFileSizeHigh * MAXDWORD) + nFileSizeLow.
nFileSizeLow
Specifies the low-order DWORD value of the file size, in bytes.
А на две операции разбил, т.к. когда тестил получалось типа косяка в [0]
← →
Galkov © (2006-12-22 11:22) [4]1) Откуда известно, что призведение двух dword-ов будет int64 ??? Народ против таких приколов всякие MulDiv-ы изобретал....
2) Приведенная ф-ла соответствует действительности в случае MAXDWORD=$100000000. Данная MSDN-нарезка из раздела Platform Builder for Microsoft Windows CE 5.0
Не знаю чему там равно MAXDWORD, но в дельфях вроде $FFFFFFFF
3) Мало ли чего на заборе пишут....
Тестировать лично у меня не получалось: мой самый большой файл, это на локалке нашел MSDN.rar - всего 1.7Г
Но когда народ спрашивал, я им выкинул такой fix, и получил радостные сообщения о соответствии показаний с другими ф.менеджерамиfunction FileSize( const Path : String ) : Int64;
type T = record L,H:DWORD end;
var FD : TWin32FindData;
FH : THandle;
begin
FH := FindFirstFile( PChar( Path ), FD );
Result := 0;
if FH = INVALID_HANDLE_VALUE then exit;
T(Result).L := FD.nFileSizeLow;
T(Result).H := FD.nFileSizeHigh;
FindClose( FH );
end;
← →
Galkov © (2006-12-22 12:08) [5]btw: В том же MSDN (но чуток в другом под-разделе) есть такое:
nFileSizeHigh
High-order DWORD value of the file size, in bytes. This value is zero unless the file size is greater than MAXDWORD. The size of the file is equal to (nFileSizeHigh * MAXDWORD+1) + nFileSizeLow.
nFileSizeLow
Low-order DWORD value of the file size, in bytes.
Думается, что здесь адекватнее говорить не о потерянной паре скобок, а о заборе
У меня MSDN April 2005 :)))))
← →
Galkov © (2006-12-22 12:47) [6]Мда... Воды не мало утекло, с тех пор как я разбил стекло :))
В сегодняшнем KOL это уже надо делать так, оказывается:function FileSize( const Path: KOLString ) : {$IFDEF _D2orD3} Integer {$ELSE} Int64 {$ENDIF};
var FD : TFindFileData;
begin
Result := 0;
if not Find_First( Path, FD ) then exit;
T(Result).L := FD.nFileSizeLow;
{$IFNDEF _D2orD3}T(Result).H := FD.nFileSizeHigh;{$ENDIF}
Find_Close( FD );
end;
← →
MTsv DN © (2006-12-22 12:50) [7]> 2) Приведенная ф-ла соответствует действительности в случае MAXDWORD=$100000000. Данная MSDN-нарезка из раздела Platform Builder for Microsoft Windows CE 5.0 Не знаю чему там равно MAXDWORD, но в дельфях вроде $FFFFFFFF
MAXDWORD := 4294967295 Причем тут 1.7ГБ???
> Тестировать лично у меня не получалось: мой самый большой
> файл, это на локалке нашел MSDN.rar - всего 1.7Г
Под БОЛЬШИМ ФАЙЛОМ, я имел ввиду размером большим 4ГБ, т.е. максимально разрешенного на FAT32. 1.7ГБ и так правильно в nFileSizeLow получается, а вот бОльший размер равен как раз (nFileSizeHigh * MAXDWORD) + nFileSizeLow
P.S. Все равно не понимаю, чем Вас код в [0] не устраивает... Я его тестировал на файлах 5 и 7 ГБ... Все правильно возвращает...
Хотя это не принципиально уже...я тему начинал из-за того, что текущая версия FileSize выдает ошибку, а какую реализацию возьмет Владимир неважно, главное, чтобы работало без "косяков"...
← →
Galkov © (2006-12-22 13:03) [8]
> Причем тут 1.7ГБ???
Тестировать мне нечем, чтобы сказать мог: ПРОВЕРИЛ, И РАБОТАЕТ ПРАВИЛЬНО, ДО ПОСЛЕДНЕГО БАЙТА. Сейчас могу только на других ссылаться.
И больше не причем.
> бОльший размер равен как раз (nFileSizeHigh * MAXDWORD) + nFileSizeLow
Не равен. Не зависимо ни от чьего мнения.
Арифметика - наука точная.
Равен может быть только в таком случае:nFileSizeHigh * (MAXDWORD+int64(1)) + nFileSizeLow
← →
MTsv DN © (2006-12-22 13:30) [9]> Не равен. Не зависимо ни от чьего мнения.
> Арифметика - наука точная.
> Равен может быть только в таком случае:
> nFileSizeHigh * (MAXDWORD+int64(1)) + nFileSizeLow
Совсем плохой стал...сорри...в [5] +1 не увидил. Да, здесь Вы правы!!!
← →
Galkov © (2006-12-22 18:31) [10]Смеха ради нашел в MSDN еще одну (третью - одну давали Вы, и она там есть, я вторую выше), но уже правильную формулу :)))
nFileSizeHigh
High-order DWORD value of the file size, in bytes. This value is zero unless the file size is greater than MAXDWORD. The size of the file is equal to (nFileSizeHigh * (MAXDWORD+1)) + nFileSizeLow.
nFileSizeLow
Low-order DWORD value of the file size, in bytes.
выделение сохранил из MSDN :)
НО. Нельзя копировать бездумно. Сумма двух dword-ов, это тоже dword, и в данном случае - нулик.
Вы зря не обратили внимания на п.1 из [4]
Если это 5-7 гиг, тоnFileSizeHigh=1
, и умножение на MAXDWORD не приводит к переполнению. Суммарная ошибка - всего 1 байт, который можно не заметить.
Для 9 гиг будет ужеnFileSizeHigh=2
, а результат произведения на MAXDWORD - 4294967294.
Почувствуйте разницу.
Ибо результатом произведения двух dword-ов будет dword
Но это больше теоретический диспут. У нас все значительно проще, и сложная арифметика не требуется.
← →
GMax (2006-12-22 20:33) [11]вот так делаю я.
это чем-то плохо ?
function GetFileSize64(FN: String): Int64;
var
FD : TWin32FileAttributeData;
begin
Result := -1;
if GetFileAttributesEx(PChar(FN),GetFileExInfoStandard,@FD) then begin
I64(Result).Hi:=FD.nFileSizeHigh;
I64(Result).Lo:=FD.nFileSizeLow;
end;
end;
правда дельфи23 не учитываю, тк не имею
← →
MTsv DN © (2006-12-22 22:03) [12]2 Galkov © - снимаю шляпу...
[6] - реально рабочий код... Мой в ауте :( Проверено на файле >10GB
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.054 c