Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
3-1177488926
vajo
2007-04-25 12:15
2007.08.05
Подскажите SQl запрос для выборки клиентов по дню рождения.


8-1162849612
Горгер
2006-11-07 00:46
2007.08.05
ValidateRgn в OpenGL-


4-1171894247
Vemer
2007-02-19 17:10
2007.08.05
Какое сообщение посылаеться при смене экранного разрешения?


15-1183877862
Ricks
2007-07-08 10:57
2007.08.05
Кличко - Брюстер — американский позор


1-1180067482
Valkyre
2007-05-25 08:31
2007.08.05
Динамическое отображения TSpeedButton





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский