【问题标题】:Cannot get data from file无法从文件中获取数据
【发布时间】:2024-06-27 05:00:01
【问题描述】:

使用JFileChooser 保存文件,一切正常:

private void saveFileDialog(){

    fileChooser = new JFileChooser(System.getProperty("employees.dat"));
    disableTextField(fileChooser.getComponents());

    fileChooser.setSelectedFile(new File("employees.dat"));
    fileChooser.setDialogTitle("File to save");

    int userSelection = fileChooser.showSaveDialog(this);
    if (userSelection == JFileChooser.APPROVE_OPTION) {
        File fileToSave = fileChooser.getSelectedFile();
        save();
        System.out.println("Save as file: " + fileToSave.getAbsolutePath());
    }
}

调用方法save()

public void save(){
    RandomAccessFile file = null;
    try {
        file = new  RandomAccessFile("employees.dat", "rw");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
     try{
         for(Employee em: list){
      if(list != null){

        file.writeUTF(em.getPps());
        file.writeUTF(em.getName());
        file.writeUTF(em.getSurname());
        file.writeUTF(em.getGender());
        file.writeUTF(em.getDep());
        file.writeInt(em.getSalary());
        file.writeUTF(em.getFullTime());
             }  
         }  

       file.close();

     }catch(IOException e1){
         System.out.println("Cant save");
     }  
}

在我的电脑上打开文件,所有数据都被记录和保存。

问题是:我无法从文件中获取数据

这是我的getFromFile 方法:

   public void getFromFile(){
    RandomAccessFile file = null;
    try {
        file = new  RandomAccessFile("employees.dat", "rw");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try{
    while ( file.getFilePointer() < file.length() ){ 

          Employee em = new Employee();

                System.out.println("Saving");
                em.setPps(file.readUTF());
                em.setName(file.readUTF());
                em.setSurname(file.readUTF());
                em.setGender(file.readBoolean());
                em.setDep(file.readUTF());
                em.setSalary(file.readInt());
                em.setFulltime(file.readBoolean());  
                list.add( em );

    }
         file.close();
         }catch(IOException e1){
             System.out.println("Cant save");
             e1.printStackTrace();
         }  
}

用于从文件中获取的我的 JFileChooser:

    openItem.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
        fileChooser = new JFileChooser(".");

        fileChooser.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            System.out.println("Action");

          }
        });

        int status = fileChooser.showOpenDialog(null);

        if (status == JFileChooser.APPROVE_OPTION) {

          File selectedFile = fileChooser.getSelectedFile();
          getFromFile();

          System.out.println(selectedFile.getParent());
          System.out.println(selectedFile.getName());
        } else if (status == JFileChooser.CANCEL_OPTION) {
          System.out.println("calceled");

        }

      }
});

控制台显示 System.out.println("Saving");,然后是 System.out.println("Cant save"); .在我看来,一切都应该正常工作,但是文件是空的,我的程序中没有出现任何新内容。

出现以下异常:

 java.io.EOFException
        at java.io.RandomAccessFile.readFully(RandomAccessFile.java:399)
        at java.io.DataInputStream.readUTF(DataInputStream.java:592)
        at java.io.RandomAccessFile.readUTF(RandomAccessFile.java:921)

【问题讨论】:

  • 您应该使用e1.printStackTrace() 来查看问题所在,而不是打印您自己的错误消息。
  • 谢谢。我现在会更新我的帖子。
  • 我很困惑,save 怎么知道你在saveFileDialog 中选择了什么文件?它只是将文件保存在当前工作目录中
  • 您在读取文件时调用了两次em.setPps(file.readUTF());,这可能会导致问题发生

标签: java io file-handling randomaccessfile eofexception


【解决方案1】:

你的“核心”问题很可能在这里......

System.out.println("Saving");
em.setPps(file.readUTF());
em.setPps(file.readUTF());
em.setName(file.readUTF());
em.setSurname(file.readUTF());
em.setGender(file.readBoolean());
em.setDep(file.readUTF());
em.setSalary(file.readInt());
em.setFulltime(file.readBoolean()); 

你给setPps打了两次电话。

此外,您使用 JFileChooser 选择的内容与文件写入/读取的位置之间没有排序规则

如果我们快速看一下读/写操作,我们可以看到双读操作

+----------------------------------+-------------------------------------+
| Write                            | Read                                |
+----------------------------------+-------------------------------------+
| file.writeUTF(em.getPps());      | em.setPps(file.readUTF());          |
+----------------------------------+-------------------------------------+
| file.writeUTF(em.getName());     | em.setPps(file.readUTF());          |
+----------------------------------+-------------------------------------+
| file.writeUTF(em.getSurname());  | em.setName(file.readUTF());         |
+----------------------------------+-------------------------------------+
| file.writeUTF(em.getGender());   | em.setSurname(file.readUTF());      |
+----------------------------------+-------------------------------------+
| file.writeUTF(em.getDep());      | em.setGender(file.readBoolean());   |
+----------------------------------+-------------------------------------+
| file.writeInt(em.getSalary());   | em.setDep(file.readUTF());          |
+----------------------------------+-------------------------------------+
| file.writeUTF(em.getFullTime()); | em.setSalary(file.readInt());       |
+----------------------------------+-------------------------------------+
|                                  | em.setFulltime(file.readBoolean()); |
+----------------------------------+-------------------------------------+

你写的和读的也有差距

例如,你用file.writeUTF(em.getGender());写性别,但你用em.setGender(file.readBoolean());读它

您可能应该使用file.writeBoolean(em.getGender());

如果它通过我的 JFileChooser 正确保存到文件中,是否意味着它们之间存在排序规则?

让我们看看你的saveFileDialog方法

private void saveFileDialog(){

    fileChooser = new JFileChooser(System.getProperty("employees.dat"));
    disableTextField(fileChooser.getComponents());

    fileChooser.setSelectedFile(new File("employees.dat"));
    fileChooser.setDialogTitle("File to save");

    int userSelection = fileChooser.showSaveDialog(this);
    if (userSelection == JFileChooser.APPROVE_OPTION) {
        File fileToSave = fileChooser.getSelectedFile();
        save();
        System.out.println("Save as file: " + fileToSave.getAbsolutePath());
    }
}

您创建了一个名为 fileToSave 的局部变量(我假设您希望将文件保存到的目录),但它只有此方法的上下文,其他人无法使用

所以,你的方法应该是……

private void saveFileDialog(){
    save();
}

基本上会达到同样的效果

我也会考虑使用 JAXB 之类的东西,这可能会让你的生活更轻松

【讨论】:

  • 谢谢,我两次都摆脱了调用步骤,但仍然是同样的问题。如果它通过我的 JFileChooser 正确保存到文件中,是否意味着它们之间存在排序规则?
  • 但是“如何”save 方法知道将文件保存在哪里?您永远不会将该信息传递给方法
  • 我只是去我想保存文件的地方,然后手动将它保存在我的文件夹中以供此应用程序使用。并在那里打开文件并保存所有数据。
  • 既然你完全忽略了JFileChooser 的结果,为什么还要它呢?它只会在您的代码中造成混乱
  • 目前我只调用了一次 setPps。而且我不确定,但是为什么我在读写性别时将布尔值和字符串放在一起,因为在我的 Employee 类中,我有以下内容:public String getGender() { return gender ? "Male":"Female"; } public void setGender(boolean gender) { this.gender = gender; }