什么都没有写入.dat文件

时间:2020-09-11 20:49:43

标签: java inputstream outputstream eofexception

我正在尝试创建一个程序,该程序读取包含.dat对象的HashMap文件。如果.dat文件为空,则应向该文件写入一个空的HashMap对象,然后,应为用户提供编辑HashMap对象的选项。

当我第一次使用一个空的.dat文件“ playlist.dat”尝试此操作时,它试图将一个空的HashMap对象写入该文件,但随后触发了一个{{1} }。我查看了文件,发现它是空的。

此处处理代码:

EOFException

3 个答案:

答案 0 :(得分:0)

几件事:

  1. 对象流非常脆弱,并不理想。使用不同版本的Java的用户可能无法以不同于序列化版本的版本打开HashMap。相反,我建议使用XML(已包含在JRE中)或JSON(我相信您需要Jackson库...除非已将其添加到JRE中)

  2. 您不需要缓冲输入或输出流。首先,缓冲流用于低效的读取和写入(例如逐行读取或写入(并非一次全部)到File。但是对象流和PrintWriter / PrintStream(不是)使用,但出于完整性考虑,我已经将其包括在内)已经具有缓冲能力。

  3. 在尝试从流中读取之前,应绝对关闭写入流。我相信如果/当您这样做时,在阅读文件时会看到文件中的内容

答案 1 :(得分:0)

BufferedOutputStream的内部缓冲区的大小等于 8192字节。直到数据超过缓冲区或您刷新,将整个数据保存在缓冲区中,这样才不会将其写入文件

似乎播放列表数据小于缓冲区大小-写入完成后,您需要在close()输出流上调用out方法,或使用try-with-resources方法

答案 2 :(得分:0)

基本上,您想要serialize一个对象,特别是HashMap的一个实例,然后反序列化它。

Java中的序列化仅存储类成员的值。它使用实际的.class文件和.dat文件的组合来反序列化对象。因此,如果序列化一个空的HashMap,则.dat文件将几乎为空。您的情况是空的,因为您没有在写入文件后关闭文件。

下面的代码是对HashMap进行序列化和反序列化的最小示例。请注意,它使用try-with-resources来确保.dat文件在使用后关闭。它还使用multi-catch处理异常。

代码说明出现在其后。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;

public class SongList {

    public static void main(String[] args) {
        File f = new File("songlist.dat");
        try (FileOutputStream fos = new FileOutputStream(f);
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            HashMap<String, String> playList = new HashMap<>();
            oos.writeObject(playList);
        }
        catch (IOException xIo) {
            xIo.printStackTrace();
        }
        try (FileInputStream fis = new FileInputStream(f);
             ObjectInputStream ois = new ObjectInputStream(fis)) {
            HashMap<?, ?> playList = (HashMap<?, ?>) ois.readObject();
        }
        catch (IOException | ClassNotFoundException x) {
            x.printStackTrace();
        }
    }
}
  • BufferedOutputStreamBufferedInputStream不是必需的。
  • 在运行时,当对HashMap进行反序列化时,java无法知道HashMap中条目的类型。这就是为什么您会收到警告。请注意,这只是警告而不是错误。这就是为什么我在读取?文件时使用.dat通配符的原因。
  • 由于您没有发布类Song的代码,因此我将HashMap的值类型更改为String,以使事情变得简单。您可以继续在代码中使用Song
  • 创建新的FileOutputStream会创建一个新的空文件。为已存在的文件创建新的FileOutputStream将删除文件内容。如果要附加到现有文件,请使用类FileOutputStream的{​​{3}}。

顺便说一句,您不应该关闭包装标准输入的Scanner

相关问题