2009-04-15 2 views
2

Мне нужно знать, насколько большой заданный буфер в памяти будет как файл на диске (usb stick), прежде чем я его напишу. Я знаю, что, если размер не падает на границу размера блока, его вероятность будет округлена, например. 1 байтовый файл занимает 4096 байт на диске. Я сейчас делаю это с помощью GetDiskFreeSpace() отработать размер дискового блока, то с помощью этого для расчета размера на диске, как это:Программно определить размер файла на диске заранее

GetDiskFreeSpace(szDrive, &dwSectorsPerCluster, 
       &dwBytesPerSector, NULL, NULL); 

dwBlockSize = dwSectorsPerCuster * dwBytesPerSector; 

if (dwInMemorySize % dwBlockSize != 0) 
{ 
    dwSizeOnDisk = ((dwInMemorySize/dwBlockSize) * dwBlockSize) + dwBlockSize; 
} 
else 
{ 
    dwSizeOnDisk = dwInMemorySize; 
} 

который, кажется, работает хорошо, НО GetDiskFreeSpace() работает только на дисках объемом до 2 ГБ в соответствии с MSDN. GetDiskFreeSpaceEx() не возвращает ту же информацию, поэтому мой вопрос в том, как еще я могу рассчитать эту информацию для дисков> 2 ГБ? Есть ли API-вызов, который я пропустил? Могу ли я принять некоторые жесткие значения в зависимости от общего размера диска?

+0

совет: это «округление до следующего кратного». Вы можете использовать block = (MemorySize + (BlockSize-1))% BlockSize; немного короче. – MSalters

+0

Это, конечно, предполагает, что в файловой системе будет нуждаться файл, содержащий N байтов. Конечно, для данных, вероятно, потребуется N байтов, но файл также содержит метаданные, которые необходимо учитывать. Размер метаданных может сильно отличаться от файловой системы. – unwind

ответ

3

MSDN только утверждает, что функция GetDiskFreeSpace() не может сообщить объем размеров больше 2 Гб. Он отлично работает для извлечения секторов на кластер и байты на сектор, я сам использовал его для очень похожего кода ;-)

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

+0

Это научит меня более внимательно читать документацию! Я только что попробовал код на своем жестком диске, и, похоже, он работает нормально. Благодарю. – binarybob

3

Размер файла на диске - это нечеткое понятие. В NTFS файл состоит из набора элементов данных. Вы primarilty думаете о «неназванный поток данных». Это атрибут файла, который, если он мал, может быть упакован с другими атрибутами в записи каталога. Apparently, вы можете сохранить поток данных до 700-800 байт в самой записи каталога. Следовательно, ваш гипотетический 1-байтовый файл будет размером в 0 байт или 700-байтовый файл.

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

+0

Я бы также добавил разреженные файлы в список исключений. –

+0

Редкие файлы не появляются спонтанно, вы должны создать их намеренно. OTOH, атрибут, который я описал, случается всегда, и сжатие файла может произойти, если каталог (или диск) сжимается. – MSalters

-3

В действии!

var size:Number = 19912; 
var sizeOnDisk:Number = size; 
var reminder:Number = size % (1024 * 4); 
if(reminder>0){ 
    sizeOnDisk = size + ((1024 * 4)- reminder) 
} 
trace(size) 
trace(sizeOnDisk)