2016-12-21 1 views
1

Мне нужно написать от Memorystream до простого Filestream. Проблема в том, что мой memystream содержит имя файла и его последовательность байтов, разделенных символом «|». Так что это примерно так: name.extension | BYTES. Код я использую, чтобы написать сейчас:Как я могу написать FileStream из Memorystream, начиная с ненулевой позиции?

Dim j As Integer = 1 
    Dim name As String 
    name = "" 
    ms.Read(temp, 0, 1) 
    Do While (UTF8.GetString(temp, 0, 1) <> "|") 
     name += UTF8.GetString(temp, 0, 1) 
     j += 1 
     ms.Read(temp, 0, 1) 
    Loop 

Вот как я получаю имя файла и это:

Dim fs As FileStream = File.Create(sf.FileName()) 'SaveFileDialog 
     ms.Seek(j, SeekOrigin.Begin) 'starting to write after "|" char 

     Do 
      ms.Read(temp, 0, 1) 
      fs.Write(temp, 0, 1) 
      j += 1 
     Loop While ms.Length - j <> 0 'YES... byte after byte 

     fs.Close() 
     fs.Dispose() 
     ms.close() 
     ms.Dispose() 

является, как я пишу этот файл. Я знаю, что могут быть вещи, которые могли бы быть написаны лучше, но именно поэтому я прошу вас о помощи. Я попытался использовать MememoryStream.WriteTo (FileStream), но он также начинает писать из имени файла. Можно ли улучшить код? Большое спасибо!

+1

Ваш подход хорош. Возможно, вы захотите увеличить размер буфера от 1, но в противном случае, если он работает, вы должны называть его днем. –

+2

Попробуйте 'ms.CopyTo (fs)' после выполнения 'Seek'. – Mark

+0

@GuillaumeCR Я так и думал, но я должен знать, когда размер буфера превышает количество оставшихся байтов запоминающего устройства. Я прав? – Dadex

ответ

1

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

using (var ms = new MemoryStream()) 
{ 
    //Prepare test data. 
    var text = "aFileName.txt|the content"; 
    var bytes = Encoding.UTF8.GetBytes(text); 
    ms.Write(bytes, 0, bytes.Length); 
    //Seek back to origin to simulate a fresh stream 
    ms.Seek(0, SeekOrigin.Begin); 

    //Read until you've consumed the | or you run out of stream. 
    var oneByte = 0; 
    while (oneByte >= 0 && Convert.ToChar(oneByte) != '|') 
    { 
     oneByte = ms.ReadByte(); 
    } 

    //At this point you've consumed the filename and the pipe. 
    //Your memory stream is now at the proper position and you 
    //can simply tell it to dump its content into the filestream. 
    using (var fs = new FileStream("test.txt", FileMode.Create)) 
    { 
     ms.CopyTo(fs); 
    } 
} 

Обратите внимание, что потоки являются одноразовыми объектами. Вместо того, чтобы закрывать и удалять, вы должны использовать конструкцию «using», поскольку она позаботится об этом для вас, даже если будет выбрано исключение.

+0

Я провел некоторое тестирование, и теперь он работает очень хорошо. Спасибо вам, ребята! – Dadex

Смежные вопросы