Как создать файл (размер: 0 байт), при удалении которого освободится 100МБ на диске?
1 Answers
В Windows под размером файла обычно понимается размер основного потока данных - именно он отображается как "размер" в проводнике (и в остальных утилитах для работы с диском).
Но кроме основного потока данных к файлу можно дописать несколько дополнительных потоков, размер данных в которых не будет включатся в общий "размер" файла. Называется эта фича Alternate Data Streams. Раньше она использовалась для совместимости с маками. Сейчас используется для хранения метаданных - например, свойств картинок - тех самых "снято, выдержка, размер" и прочих, которые можно задать в свойствах файла.
Вобщем, достаточно простого вызова CreateFile с суффиксом ":streamname" в имени файла - и можно писать на диск "неучтенные" данные. Вот пример, создающий файл с отображаемым размером в 0 байт, при удалении которого освобождается 100 мегабайт:
#include <windows.h>
#include <stdio.h>
void main()
{
HANDLE hFile, hStream;
DWORD dwRet;
hFile = CreateFile(L"C:\\temp\\testfile",
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
0,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Cannot open testfile\n");
}
else
{
// do nothing
// WriteFile(hFile, "This is testfile", 16, &dwRet, NULL);
}
hStream = CreateFile(L"C:\\temp\\testfile:stream",
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
0,
NULL);
if (hStream == INVALID_HANDLE_VALUE)
{
printf("Cannot open testfile:stream\n");
}
else
{
for (int i = 0; i < 10000000; i++)
{
WriteFile(hStream, "1234567890", 10, &dwRet, NULL);
}
}
}
Его будет выдавать ненулевой Size On Disk, отображаемый в свойствах файла в проводнике - но этот размер и для обычных файлов может не совпадать с Size.
Во всех остальных местах размер файла будет отображаться как 0.
-
1Но ведь не учет альтернативных данных используемым программным обеспечением при определении размера файла это не есть неиспользуемое дисковое пространство. Файл все же будет занимать на диске эти 100 Мб. – Vitalts Nov 11 '15 at 08:00
-
соглашусь с @Vitalts вы все таки создаете не пустой файл, хоть и данные находятся в дополнительном потоке:) но все же это плюс – Bald Nov 11 '15 at 08:05
-
1@Vitalts да, но в терминологии Windows/WinApi размер файла - это размер основного потока данных. то, что к файлу прицеплен багаж в 100 мегабайт - на размер файла не влияет (но влияет на место на диске). Например, имя файла точно так же хранится в стриме с типом ::$FILE_NAME. Но при этом почти никто не согласится, что переименование файла меняет его размер (хотя очевидно, что более длинное имя занимает на диске больше места) :) – Nov 11 '15 at 08:09
-
1@PashaPash, не могу согласится. Копирование только основного потока данных на другой носитель в данном случае сделает файл не читаемым. Это сравнимо с созданием сим линка на другом носителе. Для создания копии без потерь данных нужно скопировать и багаж в 100 Mb. Так или иначе, ваш ответ очень достоен и заслужил свои плюсы. Чего не скажешь о вопросе... – Vitalts Nov 11 '15 at 08:27
-
2Альтернативный способ создания такого файла с применением PowerShell v3+:
Set-Content -Path FileName.txt -Stream StreamName -Value ('a'*(100mb-2)). – user181245 Nov 11 '15 at 08:59 -
@PetSerAl о, спасибо за вариант - на C# прямой работы со стримами нет, и я подумал что на PS аналога тоже не будет. – Nov 11 '15 at 09:06
-
2Вариант создания из командной строки:
fsutil file createnew file.dat:hidden 100000000(впрочем, тут будет не 100 Мб, а 95 Мб). – Yaant Nov 11 '15 at 10:19 -
1В Linux подобное тоже возможно (начать можно с man xattr), но размер (обычно 4К) дополнительных данных ограничен... – avp Nov 11 '15 at 12:43