Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Размер файла


Автор: Bima 25.12.2006, 14:24
есть код:
Код

void SizeFile(void)           //   Подпрограмма определения размеров файлов 
{
int handle;
for (int i=1; i<11; i++)
   {
   if(MyEnable[i])
      {
      if (FileExists(MyFile[i]))
         {
         handle = open(MyFile[i].c_str(), O_RDONLY);
         OldSize[i]=filelength(handle);
         close(handle);
         }
      else
         OldSize[i]=(-1);
      }
   else
      OldSize[i]=(-1);
   }
}


Здесь интересны всего три строки:
Код

handle = open(MyFile[i].c_str(), O_RDONLY);
OldSize[i]=filelength(handle);
close(handle);


что бы их добавить, нужно подключить:
Код

#include <io.h>
#include <fcntl.h>


Можно, как  нибудь все это сделать одной командой??? может есть встроенная команда (для примера FileExists, определяет есть ли файл) для определения размера файла???

Автор: Romikgy 25.12.2006, 15:08
TFileStream::Size

Автор: codelord 25.12.2006, 15:23
знаю еще такие варинаты без доп подключений если есть vcl
Код

__int64 GetFileSize(AnsiString FileName)
{
__int64 h = FileOpen(FileName, fmOpenRead);
__int64 x = FileSeek(h, 0, 2); //pазмеp файла
FileClose(h);
return x;
}

или, с использованием GetFileSize, но ей всеравно нужен Handle файла:
Код

unsigned long filesize(char *dir /*Например: Temp:\*.* */)
{
HANDLE hFile;
hFile = CreateFile(dir,  // имя файла
    GENERIC_READ,                   // открываем для чтения
    0,                              // монопольно
    NULL,                           // без защиты
    OPEN_EXISTING,                  // только существующий файл
    FILE_ATTRIBUTE_NORMAL,          // нормальный файл
    NULL);
    unsigned long size;
    size=GetFileSize(hFile,NULL);
    CloseHandle(hFile);
    return size;
}

по скорости приблизительно одинаково работают, второй процентов на 15 быстрей.

Автор: Bima 25.12.2006, 15:29
а что быстрее будет работать и стабильнее, прошлый код (см. выше) или новый???

новый код:
Код

void SizeFile(void)           //Подпрограмма определения размеров файлов     
{
for (int i=1; i<11; i++)
   {
   if(MyEnable[i])
      {
      if (FileExists(MyFile[i]))
         {
         TFileStream *GetSize = new TFileStream(MyFile[i], fmOpenRead);
         OldSize[i]=GetSize->Size;
         delete GetSize;
         }
      else
         OldSize[i]=(-1);
      }
   else
      OldSize[i]=(-1);
   }
}


или вот этот код:
Код

__int64 handle;
void SizeFile(void)           //Подпрограмма определения размеров файлов     
{
for (int i=1; i<11; i++)
   {
   if(MyEnable[i])
      {
      if (FileExists(MyFile[i]))
         {
         handle = FileOpen(MyFile[i], fmOpenRead);
         OldSize[i]=FileSeek(handle, 0, 2);
         FileClose(handle);
         }
      else
         OldSize[i]=(-1);
      }
   else
      OldSize[i]=(-1);
   }
}

[/code]

Автор: Romikgy 25.12.2006, 16:33
можно еще и через
FindFirstFile
FindClose
структура
WIN32_FIND_DATA .
DWORD    nFileSizeHigh; 
    DWORD    nFileSizeLow; 
Код

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.

Автор: Anikmar 25.12.2006, 17:12
#include <IdGlobal.h>

Size = FileSizeByName("test.txt");

Автор: Bima 26.12.2006, 07:31
Цитата

#include <IdGlobal.h>

Size = FileSizeByName("test.txt"); 

Наверно это самый короткий код, но использовать компонент Indy(хотя я могу могу ошибаться), хм.

А все таки, что лучше использовать??? тут уже 4 реально работающих кода.
У меня приложение будет работать постоянно, то есть на серваке не меньше месяца. Код будет вызываться раз в минуту или реже.

Автор: codelord 26.12.2006, 08:09
по моим тестам получилось так:
самый быстрый вариант:
тот который в моем посте второй там где
Код

size=GetFileSize(hFile,NULL);

потом около 15 % отставания от него способом fseek, 
далее приблизительно с отставанием 20-25% от первого идет способ с TFileStream,
c IdGlobal у меня не заработал начал ругаться на кругом расставленные GetTickCount();
вот так. пробовал вызывать функции на несколько тыс файлов никто не ругнулся. (хотя конечно проверки добавтить не помешало бы).

Автор: W4FhLF 26.12.2006, 08:52
Цитата

А все таки, что лучше использовать??? тут уже 4 реально работающих кода.
У меня приложение будет работать постоянно, то есть на серваке не меньше месяца. Код будет вызываться раз в минуту или реже.


Любой из вышеприведённых примеров прицнипиально друг от друга ничем не отличается, на уровне системы всё сводится к CreateFile/GetFileSize(ну или аналогичные API). Так зачем использовать эти обёртки? Сразу вызывай соответствующие API, как показал codelord.

Автор: dumb 26.12.2006, 13:21
быстрее всего, по идее, должно быть таки через FindFirst, ибо при открытии файла все равно запись в каталоге читается.

Автор: W4FhLF 26.12.2006, 13:38
Код

быстрее всего, по идее, должно быть таки через FindFirst, ибо при открытии файла все равно запись в каталоге читается.


FindFirstFile работает через пару функций ZwOpenFile/ZwQueryDirectoryFile. При этом уходит куча времени на преобразование ANSI строк в UNICODE и заполнении структуры WIN32_FIND_DATA. Другое дело, если сразу работать с FindFirstFileExW, тогда можно сэкономить кучу тактов.

Пара CreateFile/GetFileSize работает через пару функци ZwCreateFile/ZwQueryInformationFile, никаких заполнений структур здесь не происходит, но тоже много времени теряется на преобразовании ANSI > UNICODE.

Отсюда вывод, что оба примерно по скорости примерно одинаковы, если только использовать их W аналоги и работать с UNICODE строками. Быстрее тут ничего не придумаешь, ну разве что вызывать ядерные функции напрямую.

Автор: dumb 26.12.2006, 13:56
время выполнения непосредственно кода системных функций в данном случае не играет большой роли - основные задержки при обращении к диску(кэш не рассматриваем). предыдущий мой пост следует понимать именно в этом ключе - в какие дисковые операции "выливаются" эти варианты.

Автор: W4FhLF 26.12.2006, 14:07
Так обращений к диску мы никак не избежим в любом случае, поэтому обсуждать это не имеет смысла. Лучше подумать как наиболее оптимально работать с функциями. Хотя, что тут думать и так всё ясно...

Автор: dumb 27.12.2006, 05:07
Цитата(W4FhLF @  26.12.2006,  14:07 Найти цитируемый пост)
Так обращений к диску мы никак не избежим в любом случае, поэтому обсуждать это не имеет смысла.

дык не про "избегание" речь, а про возможное сокращение количества обращений.
а что до скорости работы кода функций, то естественно, выигрывает CreateFile/GetFileSize(~32k/sec), чуть медленнее с vcl-обвеской(ввиду ее малого объема) в виде FileOpen/FileSeek(~30k/sec), и отчаянно тормозит FindFirstFile(~8k/sec). (note: кол-во естественно привязано к конфиге).

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

edit: "то естественно, выигрывает" - эт я, пожалуй, перевозбудился. нифига это не было очевидным, хотя интуитивно ZwQueryDirectoryFile немного настораживало... smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)