我试图从文件中读取Treemap
。我知道文件中有TreeMap
序列化,我的问题是OIS会在该文件上抛出EOFexception
。
public class FileDBMapApi {
private FileOutputStream OutPutter;
private FileInputStream Inputter;
private ObjectInputStream InputStream;
private ObjectOutputStream OutputStream;
private NavigableMap<Integer, Object> data;
private File currentFile;
private int autoIncrement;
/**
* @param dataFile is the file to use as a database
*/
public FileDBMapApi(String dataFile) {
String fullPath = "data/" + dataFile;
currentFile = new File(fullPath);
}
// initialiserar databasen
public void init() {
// checkar om filen existerar och isåfall assignar inputter och outputter till filen
System.out.println(currentFile.exists() && !currentFile.isDirectory());
if (currentFile.exists() && !currentFile.isDirectory()) {
try {
OutPutter = new FileOutputStream(currentFile);
OutPutter.flush();
Inputter = new FileInputStream(currentFile);
OutputStream = new ObjectOutputStream(OutPutter);
OutputStream.flush();
InputStream = new ObjectInputStream(Inputter);
} catch (Exception e) {
e.printStackTrace();
}
} else {
// annars så skapar den filen och assignar det istället
try {
boolean temp1 = currentFile.getParentFile().mkdirs();
boolean temp2 = currentFile.createNewFile();
if (temp2) {
OutPutter = new FileOutputStream(currentFile);
Inputter = new FileInputStream(currentFile);
OutputStream = new ObjectOutputStream(OutPutter);
InputStream = new ObjectInputStream(Inputter);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// läser in hashmapen från filen
this.convertData();
}
public void write() {
try {
PrintWriter n = new PrintWriter(currentFile);
n.close();
OutputStream.writeObject(data);
OutputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public int add(Object o) {
int id = autoIncrement;
data.put(autoIncrement, o);
autoIncrement++;
return id;
}
public Object get(int i) {
return data.get(i);
}
public void close() {
try {
OutPutter.close();
Inputter.close();
InputStream.close();
OutputStream.flush();
OutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// returnar data
public NavigableMap<Integer, Object> getAll() {
return data;
}
public long getFileSize() {
return currentFile.length();
}
// tar data från en fil och sätter in det till en hashmap
private void convertData() {
try {
if (InputStream.read() != -1) {
data = (NavigableMap) InputStream.readObject();
} else {
data = new TreeMap<>();
System.out.println(data);
}
if (!data.isEmpty()) autoIncrement = data.lastKey();
else autoIncrement = 0;
} catch (Exception e) {
e.printStackTrace();
}
}
public void closeAndWrite() {
write();
close();
}
}
抛出异常的是convertData(0
方法。我检查了相关文件,它确实包含序列化的Treemap
,它已使用write()
方法和close()
方法序列化。现在我的问题是我在存储或检索数据方面做错了什么?
答案 0 :(得分:0)
我会找到错误的地方,但实际上你的代码没有任何意义,需要彻底审查:
public class FileDBMapApi {
private FileOutputStream OutPutter;
private FileInputStream Inputter;
您不需要单独FileInput/OutputStreams
作为数据成员。删除。
// initialiserar databasen
public void init() {
// checkar om filen existerar och isåfall assignar inputter och outputter till filen
System.out.println(currentFile.exists() && !currentFile.isDirectory());
if (currentFile.exists() && !currentFile.isDirectory()) {
try {
OutPutter = new FileOutputStream(currentFile);
OutPutter.flush();
Inputter = new FileInputStream(currentFile);
OutputStream = new ObjectOutputStream(OutPutter);
OutputStream.flush();
InputStream = new ObjectInputStream(Inputter);
} catch (Exception e) {
e.printStackTrace();
}
} else {
// annars så skapar den filen och assignar det istället
try {
boolean temp1 = currentFile.getParentFile().mkdirs();
boolean temp2 = currentFile.createNewFile();
if (temp2) {
OutPutter = new FileOutputStream(currentFile);
Inputter = new FileInputStream(currentFile);
OutputStream = new ObjectOutputStream(OutPutter);
InputStream = new ObjectInputStream(Inputter);
}
} catch (Exception e) {
e.printStackTrace();
}
}
你可以减少所有令人费解的双向谈话:
try {
currentFile.getParentFile().mkdirs();
OutputStream = new ObjectOutputStream(new FileOutputStream(currentFile));
InputStream = new ObjectInputStream(new FileInputStream(currentFile));
} catch (IOException exc) {
exc.printStackTrace();
}
...虽然如果init()
投掷 IOException
而不是在内部捕捉和吸收它会更好。你编写的所有复杂代码完全没有比这更好的了。并且同时打开输出和输入文件确实没有意义,并且在Windows等某些平台上不起作用。你需要重新考虑这个。
public void write() {
try {
PrintWriter n = new PrintWriter(currentFile);
n.close();
问题出在这里。 PrintWriter
未使用,因此应将其删除,但这里的真正问题是您刚刚截断了输出文件,当通过{{1}读取时,保证会生成IOException
}。删除。
ObjectInputStream
这都是胡说八道。 public void close() {
try {
OutPutter.close();
Inputter.close();
InputStream.close();
OutputStream.flush();
OutputStream.close();
之前的flush()
是多余的,您只需要关闭close()
和InputStream
。他们会为你关闭他们的嵌套流,即使他们不这样做,关闭嵌套输出流和然后尝试刷新并关闭外部输出流是没有意义的。
OutputStream
该方法再次抛出 } catch (Exception e) {
e.printStackTrace();
}
,而不是吸收它。
IOException
这是毫无意义的。在某些操作系统(如Windows)上,在关闭文件之前,目录条目不会更新,因此您可以在此处返回零。您不应该知道文件的当前长度。
public long getFileSize() {
return currentFile.length();
}
这没有任何意义。在这里,您已经读取了一个字节并将其丢弃。由于您没有写任何额外的字节,这只会使您与流不同步。删除它。
try {
if (InputStream.read() != -1) {
这个“别的”也没有任何意义。如果文件为空或者不包含任何其他对象,则抛出 data = (NavigableMap) InputStream.readObject();
} else {
data = new TreeMap<>();
System.out.println(data);
}
,并且您应该采取任何规避措施。事实上,你应该再次抛出各种EOFException
,而不是毫无意义地替换空IOExceptions
。
TreeMap
见上文重新投掷 } catch (Exception e) {
e.printStackTrace();
}
。不要写这样的代码。
IOException
如果您确实需要,则此方法应命名为 public void closeAndWrite() {
,而您不需要。{/ p>
我检查了相关文件,确实包含序列化的
writeAndClose()
。
检查了怎么样?只有一种方法可以检查,这是通过调用Treemap
。