Вот трюк: подкласс ObjectOutputStream
и переопределить метод writeStreamHeader
:
public class AppendingObjectOutputStream extends ObjectOutputStream {
public AppendingObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {
// do not write a header, but reset:
// this line added after another question
// showed a problem with the original
reset();
}
}
Чтобы использовать его, просто проверьте, существует ли файл истории или нет, и создайте экземпляр этого добавочного потока (в если файл существует = мы append = нам не нужен заголовок) или исходный поток (в случае, если файл не существует = нам нужен заголовок).
Изменить
Я был недоволен первым наименованием класса. Это лучше: он описывает «что это такое», а не «как это сделано»
Edit
Изменено имя еще раз, чтобы уточнить, что этот поток предназначен только для добавление к существующему файлу. Он не может быть использован для создания файла new с данными объекта.
Редактировать
Добавлен вызов reset()
после этого вопроса показал, что исходная версия, которая просто переопределила writeStreamHeader
как no-op, в некоторых случаях могла создать поток, который не мог быть прочитан.
Вообще говоря, необходимо всегда избавляться от доступных ресурсов. Я, конечно, обратился бы в случае, который Вы обрисовываете в общих чертах выше. Если Вы реализуете IDisposable на классе, который реализует таймер, можно тогда использовать класс в операторе использования, подразумевая, что средства будут явно высвобождены, когда класс будет расположен.
Я предположил бы, что объект - таймер создает или использует рабочий поток в целях запустить события таймера. Расположить вызов освободит поток и ресурсы, связанные с ним. Если это так, это была бы хорошая идея звонить, располагают так, у Вас нет неиспользованных потоков, бродящих вокруг слишком долго.
Эмпирическое правило, которое я использую, должно сделать что-либо, что имеет объект IDisposable, сам IDisposable (и расположение дочерних объектов только, когда Располагают, явно назван)
существует хорошее обсуждение IDisposable в блог Joe Duffy наряду с примерами кода, которые выглядят очень похожими на тех в моей копии превосходного Руководство по проектированию Платформы книга
Путем реализации idisposable Вы будете в состоянии убрать любые внутренние ресурсы, которые также реализуют idisposable, такие как Ваш таймер.
, Кроме того, Вы были бы в состоянии изменить свой код вызова для использования использования statment.
using (SomeClass someClass = new SomeClass())
{
someClass.DoSomething();
}
Я согласен с Роулендом.
В FxCop существует правило, которое находит классы, содержащие одноразовые объекты, но не реализует должным образом IDisposable.
Я вижу, что вы задали этот вопрос год назад, но позвольте мне добавить свои 2 цента. Чуть меньше из-за инфляции :). Недавно я обнаружил в нашем приложении, что мы не избавлялись от таймеров. У нас была коллекция объектов, и у каждого объекта был таймер. Когда мы удалили элемент из коллекции, мы подумали, что это должен быть сборщик мусора. Почему-то не так с таймерами. Нам пришлось вызвать dispose для объекта в коллекции, чтобы избавиться от таймера до того, как объекты будут фактически собраны мусором.