Очистить бинарную запись с потоком памяти

У меня есть бинарник с потоком памяти, и мне нужно очистить его, если произойдет одно условие:

public void Execute() {
    MemoryStream memoryStream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(memoryStream);
    Log log = new Log(writer);
    log.Write("OK1");
    ...

    // If condition
    memoryStream = new MemoryStream();
    ...
    log.Write("OK2");
    ...
}

public class Log {

    private BinaryWriter log;

    public Log(BinaryWriter bw)
    {
        log = bw;
    }

    public void write(string msg)
    {
        log.Write(msg);
    }
}

Но проблема в том, что поток памяти пуст. Я снова попытался создать новый BinaryWriter:

public void Execute() {
    MemoryStream memoryStream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(memoryStream);
    Log log = new Log(writer);
    log.Write("OK1");
    ...

    // If condition
    memoryStream = new MemoryStream();
    writer = new BinaryWriter(memoryStream);
    ...
    log.Write("OK2");
    ...
}

public class Log {

    private BinaryWriter log;

    public Log(BinaryWriter bw)
    {
        log = bw;
    }

    public void write(string msg)
    {
        log.Write(msg);
    }
}

Но и BinaryWriter, и MemoryStream пусты.

Как я могу очистить бинарную запись с потоком памяти? Мне нужно записать окончательное содержимое потока памяти в файл.

Спасибо!


person Alberto    schedule 01.12.2013    source источник
comment
Вы создаете модуль записи двоичных файлов на recordStream, а не на memoryStream.   -  person Anton Tykhyy    schedule 01.12.2013
comment
Извините, я переименовал переменные в этом посте, чтобы было понятнее. Я исправил это в коде. Я думаю, проще идентифицировать memorystream для MemorySteam. В моем коде есть только один MemoryStream и один BinaryWriter, поэтому с другими ссылками проблем нет :)   -  person Alberto    schedule 01.12.2013


Ответы (3)


Вы хотите написать другому MemoryStream? Вы передали ссылку старого writer в Log, поэтому экземпляр Log содержит ссылку. Изменение переменной writer после этого не вступит в силу. Вам нужно либо

  1. Создайте новый журнал и передайте ему новый writer
  2. Предоставьте метод Log, чтобы разрешить манипулирование BinaryWriter, хранимым объектом извне.
person Gildor    schedule 01.12.2013
comment
Да, вы правы, конечно. Я создал новый объект журнала после создания новых BinaryWriter и MemoryStream (хотя я мог бы создать в журнале новый метод под названием reset с BinaryWriter в качестве аргумента...). - person Alberto; 01.12.2013

Этот код инициализирует объект log потоком памяти, а затем создает другой поток памяти, ссылка на который хранится в memoryStream, но бинарная запись объекта log имеет исходный поток памяти, а не новый поток памяти. Вы можете проверить это, проверив их HashCode.

person AlirezaJ    schedule 01.12.2013

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

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

Или вы можете обмануть и вызвать memoryStream.SetLength(0), чтобы заставить его начать с самого начала.

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

person Hans Passant    schedule 01.12.2013
comment
Это не обычный журнал. Я просто добрался до этого поста. В моем проекте я сериализую весь класс Microsoft, поэтому BinaryWriter необходим. Но ваш ответ правильный :) - person Alberto; 01.12.2013