Запись в MemoryStream не работает должным образом - PullRequest
1 голос
/ 07 мая 2019

Я использую библиотеку DryWetMidi для обработки некоторых данных MIDI.

Сначала я получаю данные MIDI как MemoryStream из буфера обмена:

MemoryStream ms = (MemoryStream)Clipboard.GetDataObject().GetData("Standard MIDI File");
MidiFile mid = MidiFile.Read(ms);

Затем я делаю кое-что с миди:

mid.RemoveNotes(n => n.NoteName == NoteName.FSharp);

Теперь я хочу записать это обратно в буфер обмена.Мне удалось сделать это следующим образом:

using (FileStream file = new FileStream("file.mid", FileMode.Create, FileAccess. 
{
   mid.Write(file);
}


using (MemoryStream ms2 = new MemoryStream())
using (FileStream file = new FileStream("file.mid", FileMode.Open, FileAccess.Read))
{
     byte[] bytes = new byte[file.Length];
     file.Read(bytes, 0, (int)file.Length);
     ms2.Write(bytes, 0, (int)file.Length);

     Clipboard.Clear();
     Clipboard.SetData(midiFormat, ms2);
}

File.Delete("file.mid");

Как вы можете видеть, сначала я записываю MIDI-файл в файл, затем записываю этот файл в MemoryStream, который затем записываю в буфер обмена.Это не имеет особого смысла, потому что было бы проще записать его непосредственно в MemoryStream.Кроме того, я не хочу записывать файл в файловую систему пользователя.Но есть проблема.Я попробовал это так:

using (MemoryStream ms2 = new MemoryStream())
{
    mid.Write(ms2);
}

Это не дает мне ошибки, но MemoryStream полностью пуст.Вызов ms2.Length приводит к System.ObjectDisposedException.

Как я могу записать MIDI непосредственно в MemoryStream?

РЕДАКТИРОВАТЬ: Вот ссылка на DryWetMidi Write () Метод.

Второе редактирование: Вот фрагмент кода, который не будет работать:

MemoryStream ms = (MemoryStream)Clipboard.GetDataObject().GetData(midiFormat);

MidiFile mid = MidiFile.Read(ms);
mid.RemoveNotes(n => n.NoteName == NoteName.FSharp);


MemoryStream ms2 = new MemoryStream();
mid.Write(ms2);
var T = ms2.Length; //This will throw an exception

Третье редактирование: я на 100% уверен, что опубликованный код точно такой же, как и яЯ бегу.Вот StackTrace .(Gist, потому что форматирование было ужасно на SO).

1 Ответ

3 голосов
/ 07 мая 2019

Насколько я вижу, DryWetMidi использует BinaryWriter для записи в поток. И поведение по умолчанию BinaryWriter состоит в том, что когда он удаляется, он также удаляет поток.

Вы не можете читать из MemoryStream, когда он утилизируется, но вы можете позвонить ToArray().

byte[] result;
using (MemoryStream ms2 = new MemoryStream())
{
    mid.Write(ms2);
    result = ms2.ToArray();
}
...