Чтение MemoryStream, который содержит несколько файлов - PullRequest
1 голос
/ 07 октября 2011

Если у меня есть один MemoryStream, о котором я знаю, я отправил несколько файлов (пример 5 файлов) в этот MemoryStream.Можно ли читать из этого MemoryStream и иметь возможность разбивать файл на файл?

Мой инстинкт говорит мне «нет», так как, когда мы читаем, мы читаем побайтово… Любая помощь и возможный фрагментбыло бы замечательно.Я не смог найти что-либо в Google или здесь: (

Ответы [ 5 ]

3 голосов
/ 07 октября 2011

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

Вы может использовать вместо сжатого файла, такого как ZIP-файл, для передачи нескольких файлов.

1 голос
/ 07 октября 2011

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

Итак, если вам нужно записать файлы в такой поток, целесообразно добавить дополнительную информацию. Например, начните с номера версии, затем запишите размер первого файла, запишите сам файл, а затем запишите размер следующего файла и т. Д.

Начиная с номера версии, вы можете вносить изменения в этот формат. В будущем вы можете решить, что вам также необходимо сохранить имя файла. В этом случае вы можете увеличить номер версии, создать новый формат и по-прежнему иметь возможность читать потоки, которые вы создали ранее.

Это, конечно, особенно полезно, если вы храните эти потоки тоже.

0 голосов
/ 07 октября 2011

Вы можете использовать вместо IEnumerable<Stream>.

0 голосов
/ 07 октября 2011

Поскольку вы отправляете их, вам придется отправлять их в поток таким образом, чтобы вы знали, как вытащить их. Наиболее распространенный способ сделать это - использовать спецификацию длины. Например, чтобы записать файлы в поток:

  • записать целое число в поток, чтобы указать количество файлов

Тогда для каждого файла

  • записать целое число (или long, если файлы большие), чтобы указать количество байтов в файле
  • записать файл

Чтобы прочитать файлы обратно,

  • прочитать целое число (n), чтобы определить количество файлов в потоке

Затем, повторяясь n раза,

  • прочитайте целое число (или long, если это то, что вы выбрали), чтобы определить количество байтов в файле
  • читать файл
0 голосов
/ 07 октября 2011

Вы должны реализовать это самостоятельно, что вы хотели бы сделать, это написать что-то вроде «с разделителями» в потоке. Когда вы читаете, ищите этот разделитель, и вы узнаете, когда нажмете новый файл.

Вот быстрый и грязный пример:

 byte[] delimiter = System.Encoding.Default.GetBytes("++MyDelimited++");

 ms.Write(myFirstFile);
 ms.Write(delimiter);
 ms.Write(mySecondFile);

 ....

 int len;
 do {
    len = ms.ReadByte(buffer, lastOffest, delimiter.Length);
    if(buffer == delimiter)
    {
       // Close and open a new file stream
    }
    // Write buffer to output stream
 } while(len > 0);
...