BufferedInputStream не работает со случайными поисками в файле - PullRequest
2 голосов
/ 15 сентября 2011

Процедура записи в мой файл была следующей (в режиме, который я называю некластеризованным)

  1. Запись объекта в текущую позицию файла. Обратите внимание на позицию записи в другом файле (называемом индексным файлом), чтобы я знал, куда я поместил объекты.
  2. Оставьте некоторое пространство (случайно 1/2/3/4 КБ пространства), записав ноль байтов
  3. Повторите шаги 1 и 2

Теперь я решил прочитать объекты обратно из файла. Но я хотел использовать BufferedInputStream. Однако, когда я инкапсулирую BufferedInputStream внутри ObjectInputStream, я получаю ошибки после чтения некоторых объектов. Я предполагаю, что это произойдет после Одно буферизованное чтение (т. Е. Столько объектов, сколько может поместиться в буфер, читаются один раз, в следующий раз, когда я получаю ошибку).

С другой стороны, инкапсуляция FileInputStream непосредственно внутри ObjectInputStream работает без каких-либо проблем.

При необходимости я также предоставлю код для записи файла. Не стесняйтесь спрашивать о коде ниже.

<pre> public class RecordsFileReader { RecordsFile rFile; Iterator itr; FileInputStream fis; ObjectInputStream ois;</p> <pre><code>// The constructor public RecordsFileReader(RecordsFile rFile) throws IOException, ClassNotFoundException { this.rFile = rFile; fis = new FileInputStream(rFile.getFileName()); ObjectInputStream ois2 = new ObjectInputStream(new FileInputStream(rFile.getFileName() + ".index")); rFile.recordsLocationList = (ArrayList <Long>) ois2.readObject(); itr = rFile.recordsLocationList.iterator(); /**********************************************************/ /* HERE IS THE PROBLEM. */ /* Doesnt work when I additionally use BufferedInputStream*/ /**********************************************************/ ois = new ObjectInputStream(fis); /**********************************************************/ } public Tuple readNext() throws IOException, ClassNotFoundException { if(!itr.hasNext()) return null; Long nextRecordPosition = itr.next(); fis.getChannel().position(nextRecordPosition); //System.out.println((Tuple) ois.readObject()); return ((Tuple) ois.readObject()); } public void close() throws IOException { ois.close(); fis.close(); } public boolean hasNext() { return itr.hasNext(); }

}

<pre> public class RecordsFile {</p> <pre><code>boolean clustered; private String fileName; public RecordsFile(String fileName, boolean clustered) throws IOException { this.fileName = fileName; this.clustered = clustered; } /* The byte positions at which the records are located in the file. */ ArrayList<Long> recordsLocationList= new ArrayList<Long>(); public String getFileName() { return fileName; }

}

Это изменение, которое вызывает ошибку: ois = new ObjectInputStream(new BufferedInputStream(fis, 4096)); вместо ois = new ObjectInputStream(fis);

Ошибка java.io.StreamCorruptionException: invalid type code : 00

РЕДАКТИРОВАТЬ:

Теперь я выяснил проблему. В то время как мой fis находился на новой позиции, мой бис не был пропущен на эту новую позицию. Вместо этого bis пытался читать только со старой позиции и, следовательно, исключение

1 Ответ

2 голосов
/ 15 сентября 2011

Это указывает на случай, когда байты, считываемые из потока (и из файла), интерпретируются как объект (OIS), но на самом деле эти байты являются чем-то другим (не байтовым представлением действительногообъект).Это может быть из-за того, что размер буфера указан явно (в сочетании с тем, что вы устанавливаете позицию вручную).

Я бы предложил попробовать без явного указания размера буфера.

ois = new ObjectInputStream(new BufferedInputStream(fis))

...