开发者

BufferedInputStream not working with random seeks in file

开发者 https://www.devze.com 2023-04-05 10:34 出处:网络
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 in

The write procedure to my file was as follows (in the mode which I call non-clustered)

  1. 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.
  2. Leave some space (Randomly 1/2/3/4 KB of space) by writing zero bytes
  3. 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


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))

0

精彩评论

暂无评论...
验证码 换一张
取 消