Самый быстрый размер файла в Delphi для размеров> 10 ГБ

#delphi #winapi

#delphi #winapi

Вопрос:

Хотел уточнить у вас, экспертов, есть ли какие-либо недостатки в этой функции. Будет ли это работать должным образом в различных ОС Windows? Я использую Delphi Seattle (32 и 64-разрядные EXE-файлы). Я использую это вместо Findfirst из-за его скорости.

 function GetFileDetailsFromAttr(pFileName:WideString):int64;
var
  wfad: TWin32FileAttributeData;
  wSize:LARGE_INTEGER ;
begin
  Result:=0 ;
  if not GetFileAttributesEx(pwidechar(pFileName), GetFileExInfoStandard,@wfad) then
    exit;

  wSize.HighPart:=wfad.nFileSizeHigh ;
  wSize.LowPart:=wfad.nFileSizeLow  ;
  result:=wsize.QuadPart ;
end;
  

Типичные примеры, показанные в Google с помощью этой команды, не работают для размера файла > 9 ГБ

 function GetFileAttributesEx():Int64 using 
begin
...
  result:=((amp;wfad.nFileSizeHigh) or (amp;wfad.nFileSizeLow))
  

Комментарии:

1. Второй пример неверен, поскольку он не сдвигает биты nFileSizeHigh , например: Result := (Int64(wfad.nFileSizeHigh) shl 32) or wfad.nFileSizeLow; в первом примере LARGE_INTEGER обрабатывает это за вас

2. Emm… Способ с QuadPart правильный. Способ с or определенно неправильный. Почему вы показываете последний фрагмент кода?

3. Кроме того, вы должны использовать UnicodeString вместо WideString в D2009 . WideString является строкой ActiveX / COM и обладает меньшей производительностью, чем UnicodeString . Что касается поддержки ОС, GetFileAttributesEx существует со времен XP.

4. @MBo Большая часть кода, доступного в Интернете, использует аналогичный код, и вы можете подумать, что я не исследовал, поэтому я показал этот код. например: generacodice.com/en/articolo/119049 /… по этой ссылке показан аналогичный пример, но не работает для больших файлов

5. Спасибо за подсказку по UnicodeString @Remy проверит это

Ответ №1:

Код с записью variant верен.

Но этот код

 result:=((amp;wfad.nFileSizeHigh) or (amp;wfad.nFileSizeLow))
  

просто неверно, результат не может преодолеть 32-разрядную границу

Код по ссылке в комментарии

 result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
  

неверно, потому что не учитывает, как компилятор работает с 32 и 64-разрядными значениями. Посмотрите на следующий пример, показывающий, как правильно обращаться с этой ситуацией (для значений d, e):

 var
  a, b: DWord;
  c, d, e: Int64;
  wSize:LARGE_INTEGER ;
begin
  a := 1;
  b := 1;
  c := Int64(a) or Int64(b shl 32);
  d := Int64(a) or Int64(b) shl 32;
  wSize.LowPart := a;
  wSize.HighPart := b;
  e := wsize.QuadPart;
  Caption := Format('$%x $%x  $%x', [c, d, e]);
  

Обратите внимание, что в выражении для c 32-разрядного значения значение сдвигается на 32 бита влево и теряет установленный бит, затем ноль преобразуется в 64-разрядный.

Ответ №2:

Без привязки к тому, как вы получаете размер файла: было бы даже быстрее, если бы вы использовали тип (manual), который существует уже ~ 25 лет, для присвоения размера файла непосредственно результату функции вместо использования промежуточной переменной:

   Int64Rec(result).Hi:= wfad.nFileSizeHigh;
  Int64Rec(result).Lo:= wfad.nFileSizeLow;
end;
  

На случай, если это кому-то не очевидно, вот как выглядит компиляция:

с промежуточной переменной

Выше: промежуточной переменной w: LARGE_INTEGER сначала присваиваются две 32-битные части, а затем она сама присваивается результату функции. Стоимость: 10 инструкций.

использование записи непосредственно в результате функции

Выше: запись Int64Rec используется для приведения результата функции и назначения обеих 32-битных частей напрямую, без необходимости в какой-либо другой переменной. Стоимость: 6 инструкций.

Используемая среда: Delphi 7.0 (Сборка 8.1), версия компилятора 15.0, исполняемый файл Win32, оптимизация кода: включена.

Комментарии:

1. Почему это должно быть быстрее?

2. Это не быстрее.

3. Не идет ни в какое сравнение со стоимостью определения размера файла

4. Вы проверили и пришли к выводу, что в оптимизированном коде вообще есть какая -либо разница? Не похоже, что это какая-то продвинутая, ультрасовременная возможность оптимизации. Это то, что у нас было буквально десятилетиями.

5. На вас лежит ответственность за то, чтобы показать, что это быстрее, а не на нас. У вас есть ответ на это утверждение.