Reputation: 8198
The write procedure to my file was as follows (in the mode which I call non-clustered)
- Write an object to the current position of the file. Note the position of write in another file (called the index file) so I know where have I placed the objects.
- Leave some space (Randomly 1/2/3/4 KB of space) by writing zero bytes
- Repeat steps 1 and 2
Now I decided to read the objects back from the file. But I wanted to use BufferedInputStream
. However when I encapsulate a BufferedInputStream
inside an ObjectInputStream I get errors after reading some of the objects. I am guessing this happens after One buffered Read (i.e. as many objects as can fit in the buffer are read once, the next time I get an error).
On the Other hand encapsulating a FileInputStream
directly inside a ObjectInputStream
works without any problem.
If needed, I will provide the file writing code too. Feel free to ask anything about the code below.
public class RecordsFileReader {
RecordsFile rFile;
Iterator itr;
FileInputStream fis;
ObjectInputStream ois;
// 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();
}
}
public class RecordsFile {
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;
}
}
This is the change that is causing the error :
ois = new ObjectInputStream(new BufferedInputStream(fis, 4096));
instead of ois = new ObjectInputStream(fis);
The error is java.io.StreamCorruptionException: invalid type code : 00
EDIT :
I have now figured out the problem. While my fis was being positioned to a new position, my bis was not being skipped to that new position. Instead bis was trying to read from the old position only and hence the exception
Upvotes: 3
Views: 1402
Reputation: 7523
This is indicative of a case where the bytes being read back from the stream ( and from the file ) are being interpreted as an object ( by the OIS ) but actually these bytes are something else ( not a byte representation of an actual object ). This may be because of the buffer size being specified explicitly ( combined with the fact that you are setting the position manually ).
I would suggest to try without specifying the buffer size explicitly.
ois = new ObjectInputStream(new BufferedInputStream(fis))
Upvotes: 2