【问题标题】:Java - Read loosely structured data from fileJava - 从文件中读取结构松散的数据
【发布时间】:2019-05-07 09:25:05
【问题描述】:

我目前正在尝试了解 Java 代码的行为方式以及处理输入和输出文件的方式。据我了解如何逐行读取文件的内容并将它们放入数组中,我很难理解如何从文件中读取每 n 行出现的某些值,然后将它们放入数组中. 例如,我有一个如下所示的输入测试文件:

2
Australia
John
42
Blue
USA
Jeremmy
15
Black

第一行是数组的大小。以下几行是我想从文件中读取并放入所述数组中的内容(在此示例中,我将其设置为:国家、姓名、年龄、眼睛颜色)。换句话说,我想读取每四行出现的一些对象属性,以便稍后在我选择时将它们打印出来,例如其中一个人。 现在我被困在这里,不知道如何前进,因为大多数人没有尝试对这样的文件进行操作。

   private static String[] readPeople(File file) {
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        String sizeText = br.readLine();
        int size = Integer.parseInt(sizeText);
        String[] peopleSet= new String[size];

        for (int i = 1; i < size; i++) {
            if (i % 2 != 0) {
                String peopleInfo= br.readLine();
                peopleSet[i] = peopleInfo;
            }
        }
        return peopleSet;
    } catch (IOException ex) {
        System.err.println(ex);
        return new String[0];
    }
}

【问题讨论】:

  • 你能用列表代替吗?

标签: java arrays serialization file-io filereader


【解决方案1】:

我给你这个代码。

    File Read_File = new File("file_path"); 

    BufferedReader br = null;

    try {
        br = new BufferedReader(new FileReader(Read_File));
        String line;
        int line_number = 0;

        int size = Integer.parseInt(br.readLine());



        for (int try_ = 0; try_ < size; try_++) {
            String read = br.readLine();
            for(int try_four = 0; try_four<4; try_four++) {
                //save input operation
            }
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null)
            try {
                br.close();
            } catch (IOException e) {
            }
    } 

但使用列表是最好的方法。

【讨论】:

    【解决方案2】:

    用冒号分隔可能更容易

    您的条目是否在文件中的值之间用冒号分隔:

    Australia:John:42:Blue
    USA:Jeremmy:15:Black
    

    然后在你的文件解析器中:

    private static List<Person> readPeople(File file) {
        List<Person> people = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
          String line = "";
          while((line = br.readLine()) != null) {
            String[] args = line.split(":");
            String country = args[0];
            String name = args[1];
            int age = Integer.parseInt(args[2]);
            String eyeColor = args[3];
    
            Person p = new Person(name, country, age, eyeColor);
            people.add(p);
          }
        } catch (IOException ex) {
          System.err.println(ex);
        } 
        return people;
    }
    

    最后定义 Person 类

    class Person {
       String name;
       String country;
       int age;
       String eyeColor;
    
       public Person(String name, String country, int age, String eyeColor) {
          this.name = name;
          this.country = country;
          this.age = age;
          this.eyeColor = eyeColor;
       }
    
       @Override
       public String toString() {
         return String.format("%s:%s:%d:%s", country, name, age, eyeColor);
       }
    }
    

    根据需要添加错误检查和 getter/setter

    这将返回您文件中定义的人员列表,您可以通过在返回列表对象上调用 .size() 来检查列表的大小。

    更新

    添加了 toString() 覆盖以创建冒号分隔条目,以便将其写入文件或控制台

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      问题是您的代码仅在条件为真时从文件中读取。不管你循环多少次,文件内容只有在你用br.readLine()实际阅读时才会前进。

      for (int i = 1; i < size; i++) {
          if (i % 2 != 0) {
              String peopleInfo= br.readLine();
              peopleSet[i] = peopleInfo;
          }
      }
      

      也不清楚您要阅读哪些行。此代码将循环size 次 (2) 但每隔一次只读取一行,因此它只会读取“澳大利亚”。

      如果您想读取人名(“John”和“Jeremmy”),它们是每四个一组中的第三行,您可以这样做:

      for (int i = 1; i < size; i++) {
          for (int j = 0; j < 4; j++) {
              String line = br.readLine();
              if (j % 4 != 2) {
                  people[i] = line;
              }
          }
      }
      

      这会读取所有八行(从“Australia”到“Black”)。对于每个人,j 的值将从0 变为3;因此,第三行是j % 4 == 2

      它将名称存储到长度为 2 的数组 people 中。我将其从 peopleSet 重命名,因为它不是 Java Set。原始名称具有误导性。

      【讨论】:

        猜你喜欢
        • 2022-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-16
        • 1970-01-01
        • 1970-01-01
        • 2014-12-30
        • 1970-01-01
        相关资源
        最近更新 更多