Перш за все скажемо, що мова тут піде про файлових системах FAT і NTFS, як найбільш поширених, і нічого не буде сказано про файлових системах, використовуваних в не-Windows системах, оскільки такі системи лежать поза сферою інтересів автора. А тепер - до справи.
Здавалося б, яка неоднозначність може бути, якщо говорити про розмір файлу. Скільки в нього даних записали, такий і розмір (або довжина). Скільки в ньому є байтів від початку до кінця (і це число записано в файлової системі в якості розміру файлу), такий і розмір, чи не так? Як казав Шельменко-денщик, так то воно так, та тільки трошечкі не так.
Проведіть експеримент. Візьміть будь-який виконуваний файл і виконайте його копіювання командою
copy що-то.exe щось-другое.exe
Якщо ви раніше з цим стикалися, то вже знаєте, що результуючий файл вийде набагато коротше вихідного і не буде копією. Причина проста: програма copy, запущена без параметра / b, копіює файл до тих пір, поки не зустріне байт з кодом 27h, цей символ називається «кінець файлу».
Отже, у нас вже є два різних ознаки кінця файлу - по числу, записаному в файлової системі, і по спеціальному байту в тілі файлу. Правда, варто відзначити, що друга ознака залишився з тих часів, коли файли були переважно текстовими і зараз практично не застосовується.
У файлових системах, які використовують кластери, а FAT і NTFS відносяться саме до таких ФС, є ще третій розмір - розмір файлу на диску, тобто сумарний розмір кластерів, відведених цього файлу. У файлових системах FAT цей розмір більше розміру власне файлу або дорівнює йому. Різниця між розмірами, якщо вона є, - так званий хвіст файлу - це марно пропадає місце на диску, плата за розміщення файлів по кластерам, а не встик один за одним, хоча файлові системи з таким розміщенням файлів теж існують.
Втім, іноді це місце використовується. Зокрема, за часів дискет існували програми, які дозволяли записувати дані в хвости файлів, щоб таємно передати на таких дискетах інформацію. Адже стандартними засобами отримати доступ до хвостів файлів можна.
Якщо включити в розгляд NTFS, то картина доповниться новими штрихами.
Перш за все, розмір файлу на диску може виявитися менше власне розміру файлу.
Якщо тіло файлу поміщається в вільну область файлового запису MFT, то цей файл не займає на диску жодного кластера.
Максимальний розмір такого файлу залежить від розміру запису і становить приблизно 600 байтів для запису дрібного розміру (1 Кб) та 3600 - для запису великого розміру (4 Кб). Слід, утім, зазначити, що до недавнього часу Windows показувала розмір такого файлу на диску рівним одному кластеру, хоча фактично жодного кластера файлу не виділене.
Якщо файл стиснутий, то його розмір на диску може бути помітно менше власне довжини файлу (кількості даних в ньому).
Додатково ускладнюють картину так звані розріджені файли. У них корисні дані міститися тільки в певних ділянках файлу, а інша частина файлу не використовується зовсім. Візьмемо як приклад файл журналу змін \ $ Extend \ $ UsnJrnl, наявний майже на кожному комп'ютері (не намагайтеся побачити його в провіднику або інших диспетчерів файлів, не вийде).
Він може мати довжину кілька гігабайт, але значущих даних містить при цьому зазвичай тільки 32 мегабайта в самому кінці. А інша частина взагалі ніяких даних не містить, місця на диску не займає, і при спробі прочитати дані з цієї частини система видасть набір нулів, навіть не звертаючись до диска.
Якщо у читача виникне бажання поекспериментувати з розрідженими файлами, такий файл можна створити за допомогою команди fsutil sparse. А на дозвіллі можна обміркувати, яка ж справжня довжина файлу, якщо система записала в відповідну графу число 4 Гб, а реальних даних у файлі тільки 32 Мб і на диску він займає теж 32 Мб.
І, нарешті, розповімо ще про одну довжині: довжині дійсних даних (valid data). Ця довжина і встановлюють її функції представляють інтерес майже виключно для програмістів, проте зрідка з нею можуть зіткнутися і звичайні користувачі.
У файлових системах FAT такого поняття не існує, і функції, які використовують цю величину, записують в тіло файлу на відповідних місцях нулі. В NTFS ця довжина є характеристикою файлу.
Спробуємо пояснити, про що йде мова, на прикладі. Візьміть флешку (флешка використовується для наочності, оскільки вона повільніше жорсткого диска працює з великими обсягами даних) розміром від гігабайти, отформатированную в FAT32, і створіть на ній великий файл командою
fsutil file createnew k: \ пробний.txt 900000000
Якщо буква, привласнена флешці, відрізняється від К, то виправте команду відповідним чином.
Ви побачите, що процедура створення файлу виявиться досить тривалої, півхвилини або навіть більше (хоча повідомлення «файл створений» з'явиться відразу ж, появи запрошення командного рядка доведеться почекати). Це зовсім не дивно, адже в описі команди ( https://technet.microsoft.com/en-us/library/cc788058.aspx ) Сказано, що створюваний файл складається з нулів. А файл у нас вийшов 858 мегабайт, так що його запис і повинна зайняти не таке вже мале час.
Тепер відформатуйте флешку в NTFS, для чистоти експерименту краще взяти ту ж саму, і повторіть створення файлу. На цей раз операція пройде практично моментально. Записувати нулі в тіло файлу вже не треба, досить розподілити місце під файл і встановити для нього довжину дійсних даних рівною нулю. У тілі файлу залишиться «сміття», який був записаний в цих секторах, але при читанні даних звернення до цих даних не відбудеться - виявивши, що довжина дійсних даних дорівнює нулю, все, що далі цього нуля, система читати не стане - адже ці дані недійсні. Їх можна зробити дійсними, якщо змінити значення довжини дійсних даних.
Розглянемо це на прикладі. Створіть новий файл на одному з робочих дисків, отформатированном в NTFS. Сотні мегабайт абсолютно не обов'язкові, десятка-другого кілобайт буде цілком достатньо:
fsutil file createnew C: \ пробний.txt 10000
Тепер відкрийте його за допомогою будь-якого переглядача файлів, наприклад FAR.
Як бачимо, в файлі дійсно нулі. Але якщо подивитися на цей файл за допомогою будь-якого редактора дисків, що звертається до секторам безпосередньо, наприклад dmde, то картина буде інша.
Якщо ми відкриємо тому З як логічний пристрій і подивимося на вміст файлу, то побачимо ті ж самі нулі.
Але якщо відкрити диск як фізичний пристрій, то в тому ж самому секторі (зверніть увагу на номери LBA - різниця в 63 виникла через те, що початок розділу зрушено щодо початку диска) побачимо дані, які раніше були записані в якийсь пізніше віддалений файл.
І якщо ми збільшимо довжину дійсних даних, то побачимо ці дані у файлі. Встановимо цю довжину рівною 300 байт:
fsutil file setvaliddata C: \ пробний.txt 300
Зверніть увагу що параметр в цій команді не можна ставити довільно, але повинен бути не менше поточного значення довжини дійсних даних і не більше розміру файлу. Зменшити довжину дійсних даних цією командою можна.
Тепер знову подивися на вміст файлу. Зауважте, що ніяких даних ми в нього не записували!
Чисто випадково вийшло, що в цьому файлі досить багато осмисленого тексту, що робить картину більш наочною. 300 десяткових байтів - це 12c шістнадцяткових, і як раз на цьому байті обривається текст і починаються нулі. Якщо зрушити кордон дійсних даних ще далі, то «проявляться» і наступні рядки.
Підведемо підсумки
Є дві фізичних довжини файлу - це розмір файлу, записаний в файлової системі і місце, займане на диску. Також є дві логічних довжини файлу - це ознака кінця файлу (байт EOF - 27h) і довжина дійсних даних. Як складову частину логічної довжини можна розглядати і порожні області в розріджених файлах - згадайте \ $ Extend \ $ UsnJrnl, де великий масив відсутніх даних завершується тридцятьма двома мегабайтами дійсних.
Отже, зазвичай, коли говорять про довжину файлу, мають на увазі число, яке зберігається в файлової системі. Але, як бачите, можливі варіанти!
Ви можете висловити свою подяку автору і стимулювати його на подальшу творчість, перевівши невелику суму за допомогою Пейпал http://paypal.me/Leyko , Переведенням на карту ощадбанку 6390 0238 9021 6390 91 або через яндекс-гроші.
Скільки в ньому є байтів від початку до кінця (і це число записано в файлової системі в якості розміру файлу), такий і розмір, чи не так?