Предварительное выделение файлового пространства в C#?

StackOverflow https://stackoverflow.com/questions/98774

  •  01-07-2019
  •  | 
  •  

Вопрос

Я создаю приложение для загрузки, и я хочу предварительно рассказать комнату на жестком плане для файлов, прежде чем они на самом деле будут загружены, поскольку они потенциально могут быть довольно большими, и никто не любит видеть »этот диск заполнен, удалите несколько файлов и попробуйте еще раз. " Итак, в этом свете я написал это.

// Quick, and very dirty
System.IO.File.WriteAllBytes(filename, new byte[f.Length]);

Это работает, по крайней мере, до тех пор, пока вы не загрузите файл размером в несколько сотен МБ или, возможно, даже ГБ, и вы не введете Windows в безумие, если не полностью уничтожите файл подкачки и вообще не уничтожите память вашей системы.Упс.

Итак, немного поразмыслив, я приступил к следующему алгоритму.

using (FileStream outFile = System.IO.File.Create(filename))
{
    // 4194304 = 4MB; loops from 1 block in so that we leave the loop one 
    // block short
    byte[] buff = new byte[4194304];
    for (int i = buff.Length; i < f.Length; i += buff.Length)
    {
        outFile.Write(buff, 0, buff.Length);
    }
    outFile.Write(buff, 0, f.Length % buff.Length);
}

Это работает, ну даже, и не страдает от серьезной проблемы с памятью, свойственной последнему решению.Однако он по-прежнему медленный, особенно на старом оборудовании, поскольку записывает данные (потенциально объемом в ГБ) на диск.

Вопрос в следующем:Есть ли лучший способ добиться того же?Есть ли способ заставить Windows создать файл размера x и просто выделить место в файловой системе, а не записывать тонну данных?Меня вообще не волнует инициализация данных в файле (протокол, который я использую — bittorrent — предоставляет хэши для файлов, которые он отправляет, поэтому худший случай для случайных неинициализированных данных — это то, что я получаю счастливое совпадение и часть файла верно).

Это было полезно?

Решение

FileStream.SetLength это тот, который вам нужен.Синтаксис:

public override void SetLength(
    long value
)

Другие советы

Если вам нужно создать файл, я думаю, вы можете сделать что-то вроде этого:

using (FileStream outFile = System.IO.File.Create(filename))
{
    outFile.Seek(<length_to_write>-1, SeekOrigin.Begin);
    OutFile.WriteByte(0);
}

Где length_to_write — это размер записываемого файла в байтах.Я не уверен, что у меня правильный синтаксис C# (не на компьютере для тестирования), но в прошлом я делал подобные вещи на C++, и это работало.

К сожалению, вы не сможете добиться этого, просто стремясь до конца.Это приведет к тому, что длина файла станет огромной, но фактически не сможет выделить дисковые блоки для хранения.Поэтому, когда вы приступите к записи файла, он все равно не удастся.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top