我文件的写入过程如下(在我称之为非群集的模式中)
- 将对象写入文件的当前位置。请注意写入另一个文件(称为索引文件)的位置,以便知道放置对象的位置。
- 通过写入零字节
留出一些空间(随机1/2/3/4 KB的空间)- 重复步骤1和2
醇>
现在我决定从文件中读取对象。但我想使用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试图仅从旧位置读取,因此异常
答案 0 :(得分:2)
这表示从流(和文件)读回的字节被解释为对象(由OIS),但实际上这些字节是其他东西(不是实际的字节表示)对象)。这可能是因为显式指定了缓冲区大小(结合您手动设置位置的事实)。
我建议尝试不明确指定缓冲区大小。
ois = new ObjectInputStream(new BufferedInputStream(fis))