Запись в конце файла - PullRequest
6 голосов
/ 16 мая 2010

Я работаю в системе, которая требует высокой производительности файлового ввода-вывода (с C #). По сути, я заполняю большие файлы (~ 100 МБ) от начала файла до конца файла. Каждые ~ 5 секунд я добавляю ~ 5 МБ к файлу (последовательно от начала файла), при каждой массе я очищаю поток. Каждые несколько минут мне нужно обновлять структуру, которую я пишу в конце файла (какие-то метаданные).

При промывке каждого из них у меня нет проблем с производительностью. Однако при обновлении метаданных в конце файла я получаю очень низкую производительность. Я предполагаю, что при создании файла (что также должно быть сделано очень быстро), файл на самом деле не выделяет все 100 МБ на диске, и когда я сбрасываю метаданные, он должен распределять все пространство до конца файла.

Ребята / Девочки, есть идеи, как мне преодолеть эту проблему?

Большое спасибо!

Из комментария:

Вообще говоря, код выглядит следующим образом: сначала файл открывается:

m_Stream = new FileStream(filename, 
         FileMode.CreateNew, 
         FileAccess.Write, 
         FileShare.Write, 8192, false); 
m_Stream.SetLength(100*1024*1024);

Каждые несколько секунд я пишу ~ 5 МБ.

m_Stream.Seek(m_LastPosition, SeekOrigin.Begin); 
m_Stream.Write(buffer, 0, buffer.Length); 
m_Stream.Flush(); 
m_LastPosition += buffer.Length;  // HH: guessed the +=
m_Stream.Seek(m_MetaDataSize, SeekOrigin.End); 
m_Stream.Write(metadata, 0, metadata.Length); 
m_Stream.Flush();  // Takes too long on the first time(~1 sec).

Ответы [ 4 ]

2 голосов
/ 17 мая 2010

Как указано выше, не имеет смысла (при условии, что у вас должны быть метаданные в конце файла), сначала напишите это.

Это сделало бы 2 вещи (при условии не разреженного файла) ... 1. выделить общее пространство для всего файла 2. сделайте все следующие операции записи немного быстрее, так как пространство готово и ожидает.

Разве вы не можете сделать это асинхронно? По крайней мере, приложение может перейти к другим вещам.

1 голос
/ 16 мая 2010

Вы пробовали метод AppendAllText ?

0 голосов
/ 17 мая 2010

Как насчет использования BufferedStream?

http://msdn.microsoft.com/en-us/library/system.io.bufferedstream(v=VS.100).aspx

0 голосов
/ 16 мая 2010

Ваш вопрос не совсем понятен, но я предполагаю, что вы создаете файл, пишете 5 МБ, затем ищите 100 МБ и записываете метаданные, затем возвращаетесь к 5 МБ и пишете еще 5 МБ и т. Д.

Если это так, то это проблема файловой системы. Когда вы расширяете файл, NTFS должна чем-то заполнить пробел. Как вы говорите, файл не выделяется, пока вы не напишите в него. В первый раз, когда вы пишете метаданные, файл имеет длину всего 5 МБ, поэтому при записи метаданных NTFS должна выделить и выписать 95 МБ нулей, прежде чем записать метаданные. Я огорчен тем, что это также происходит синхронно, так что вы даже не выигрываете, используя перекрывающийся ввод-вывод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...