BufferedInputStream无法在文件中使用随机搜索

时间:2011-09-14 20:19:10

标签: java file-io bufferedinputstream

我文件的写入过程如下(在我称之为非群集的模式中)

  
      
  1. 将对象写入文件的当前位置。请注意写入另一个文件(称为索引文件)的位置,以便知道放置对象的位置。
  2.   
  3. 通过写入零字节
  4. 留出一些空间(随机1/2/3/4 KB的空间)   
  5. 重复步骤1和2
  6.   

现在我决定从文件中读取对象。但我想使用BufferedInputStream。但是当我在ObjectInputStream中封装BufferedInputStream时,在读取一些对象后会出现错误。我猜这发生一个缓冲读取之后发生(即,一旦读取缓冲区中可以容纳的对象,下次出现错误时)。

另一方面,将FileInputStream直接封装在ObjectInputStream内,没有任何问题。

如果需要,我也会提供文件编写代码。请随意询问以下代码。

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

}

}

// 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;
}

}

代替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));

编辑:

我现在已经找到了问题所在。当我的fis被定位到一个新职位时,我的二分并未被跳到这个新职位。相反,bis试图仅从旧位置读取,因此异常

1 个答案:

答案 0 :(得分:2)

这表示从流(和文件)读回的字节被解释为对象(由OIS),但实际上这些字节是其他东西(不是实际的字节表示)对象)。这可能是因为显式指定了缓冲区大小(结合您手动设置位置的事实)。

我建议尝试不明确指定缓冲区大小。

ois = new ObjectInputStream(new BufferedInputStream(fis))