работа с ObjectInputStream

У меня есть несколько объектов, хранящихся в файле. Это касается ObjectInputStream. Если у меня есть код ниже:

FileInputStream fis = new FileInputStream(filename);

ObjectInputStream ois = new ObjectInputStream(fis);

Object obj1 = (Object)ois.readObject();

ois.close();
 ois = new ObjectInputStream(fis);

Object obj2 = (Object)ois.readObject();

Мой вопрос: будет ли readObject, вызываемый из второго потока объектов (obj2), 1-м или 2-м объектом в файле


person Zen    schedule 16.06.2011    source источник
comment
Разве ois.close(); не закроет также fis? Если это так, второе чтение может просто завершиться ошибкой.   -  person Vineet Reynolds    schedule 17.06.2011
comment
Что, если я не закрою поток, т.е. не используйте ois.close(). Кроме того, если я закрою fis.close(), будет закрыт как ObjectInputStream   -  person Zen    schedule 17.06.2011


Ответы (2)


Фактически это вызовет исключение. Вызов close для ObjectInputStream также закроет FileInputStream.

person Perception    schedule 16.06.2011
comment
Что, если я не закрою поток, т.е. не используйте ois.close(). Кроме того, если я закрою fis.close(), будет закрыт как ObjectInputStream - person Zen; 17.06.2011
comment
@Tarun Это не сработает; ObjectInputStream выполняет внутреннюю буферизацию. Вам либо нужно продолжать использовать тот же ObjectInputStream, либо вам нужно начать с нового FileInputStream. - person Brett Kail; 17.06.2011
comment
@Tarun - Есть ли конкретная проблема, которую вы пытаетесь решить? Похоже, вы хотите сохранить позицию чтения во входных потоках в случае сбоя или другого неожиданного закрытия файлового потока. Так ли это? - person Perception; 20.06.2011

Это зависит от того, как вы хранили объекты. Если вы использовали один единственный поток ObjectOutputStream, вам также лучше использовать один единственный поток ObjectInputStream.

Если вы использовали отдельные потоки для вывода, вы также должны использовать отдельные потоки для ввода. Но это не очень рекомендуется.


Для вашей «постоянной очереди» я бы рекомендовал что-то вроде этого:

На стороне отправки:

  • Создайте ByteArrayOutputStream, оберните вокруг него ObjectOutputStream.
  • Запишите объект в OOS и закройте OOS.
  • Получите byte[] и запишите его вместе с заголовком, указывающим длину вашего потока очереди.

На принимающей стороне:

  • прочитать длину заголовка из потока очереди.
  • прочитать byte[] заданной длины из потока очереди.
  • создайте ByteArrayInputStream из этого массива и оберните вокруг него ObjectInputStream.
  • прочитать один объект из OIS, закрыть OIS.

Когда вы сохраняете части своей очереди, убедитесь, что вы всегда сохраняете целые сообщения (т.е. заголовок вместе с объектом).

Конечно, может быть проще использовать уже существующие решения, такие как JMS (где вы должны создать ObjectMessage и отправить его в очередь).

person Paŭlo Ebermann    schedule 16.06.2011
comment
в основном, я пытаюсь создать постоянную очередь. - person Zen; 18.06.2011
comment
@Tarun: для постоянной очереди вы, вероятно, захотите использовать отдельные ObjectOutputStreams. Я только что отредактировал ответ для вероятного решения. - person Paŭlo Ebermann; 18.06.2011