如何从 txt 中读取数据并每 2 行保存到数组中并删除 header

How to read data from txt and save into array every 2 lines and remove the header

我想从文本中读取数据,然后我将删除文本的header并将数据保存到每2行的数组中,因为它仍然继续数据。

visitor.txt

    1                   DAILY REPORT VISITOR
                            DATE : 02-02-22
    0+------------------------------------------------------------------+
        NO.     DATE            NAME                ADDRESS
        PHONE           BIRTHDAY        NEED                              
     +------------------------------------------------------------------+
          1     02-02-22        ELIZABETH ZEE       WASHINGTON DC
        +32 62          18-10-1985      BORROW BOOK
          2     02-02-22        VICTORIA GEA        BRUSEELS
        +32 64          24-05-1986      VISITOR
          3     02-02-22        GEORGE PHILIPS      BRUSEELS
        +32 76          02-05-1990      VISITOR 

我想要这样保存到数组中的数据。

1       02-02-22        ELIZABETH ZEE       WASHINGTON DC       +32 62          18-10-1985      BORROW BOOK
2       02-02-22        VICTORIA GEA        BRUSEELS            +32 64          24-05-1986      VISITOR
3       02-02-22        GEORGE PHILIPS      BRUSEELS            +32 76          02-05-1990      VISITOR

这是代码

BufferedReader bR = new BufferedReader(new FileReader(myfile));
int i =0;

String line;
        
try {
    while (line = bufferedReader.readLine()) != null) {
    i++;
    String data = line.split("\s", "")

    if(data.matches("[0-9]{1,3}\s.+")) {
        String[] dataArray = data.split("\s", -1);
        String[] result = new String[30];

        System.arraycopy(fileArray, 0, result, 0, fileArray.length);

        String data1 = line.get(i).split("\s", "")
        String[] fileArray1 = data.split("\s", -1);
        String[] result1 = new String[30];
 
        System.arraycopy(fileArray1, 0, result1,0,fileArray1.length);       
    }
    
}

这里的问题是,我认为这段代码无效,因为它会从 data 和 data1 读取第二行两次。我希望每 2 行像文本结果一样保存到数据库中的一行。你有什么解决办法吗?

对我来说,一行被多次阅读似乎不太可能。尝试调试您的代码,看看是否确实发生了这种情况。

否则,您真的可以在开始处理之前跳过第一行:

BufferedReader bR = new BufferedReader(new FileReader(myfile));
int i =0;

String line;
    
try {
    // alternative one
    String firstline = bufferedReader.readLine();
    String secondline = bufferedReader.readLine();
    String mergedline = firstline + secondline; // the linefeed should have been removed but the data is retained

    // alternative two
    StringBuilder sb = new StringBuilder();
    sb.append(bufferedReader.readLine()); // first line
    sb.append(bufferedReader.readLine()); // second line
    ... = sb.toString(); // now do something with the merged lines

    // the other stuff
    while (line = bufferedReader.readLine()) != null) {
        // process your data lines here
    }

}
  • 结果实际上有一个动态的记录数。然后是一个固定大小的数组 不再适合。使用 List<String\[\]> 代替:list.add(stringArray)list.get(i)list.size()list.isEmpty().
  • header好像有两行,但我可能错了。
  • 我看到带有 space 的字段,因此无法拆分 \s+(一个或多个白色 space 字符)。我确实在 \s\s+ 分手了。也许你应该更好地使用 line1.substring(i1, i2).
  • 的固定长度字段边界
  • FileReader 使用您当前计算机上的编码(=不可移植的文件)。我已经说得很清楚了。如果它始终是 US-ASCII 文件,没有特殊字符,则可以使用 StandardCharsets.US_ASCII。然后您可以 运行 Linux 服务器上的软件,通常使用 UTF-8。

因此无需检查数据格式(然而这是有道理的):

private void Whosebug() throws IOException {
    List<String[]> data = loadData("mydata.txt");
    System.out.println(data.size() + " records read");
    for (String[] fields: data) {
        System.out.println(Arrays.toString(fields));
    }
}

private List<String[]> loadData(String myFile) throws IOException {
    List<String[]> data = new ArrayList<>();
    Path path = Paths.get(myFile);
    try (BufferedReader bufferedReader =
            Files.newBufferedReader(path, Charset.defaultCharset())) {
        if (bufferedReader.readLine() != null
                && bufferedReader.readLine() != null) { // Skip both header lines.
            String line1, line2;
            while ((line1 = bufferedReader.readLine()) != null
                    && (line2 = bufferedReader.readLine()) != null) {

                String[] fields1 = line1.split("\s\s+", 4); // Split on at least 2 spaces.
                if (fields1.length != 4) {
                    throw new IOException("Wrong number of fields for first line: " + line1);
                }
                String[] fields2 = line2.split("\s\s+", 3); // Split on at least 2 spaces.
                if (fields1.length != 3) {
                    throw new IOException("Wrong number of fields for second line: " + line2);
                }
                String[] total = Arrays.copyOf(fields1, 7);
                System.arraycopy(fields2, 0, total, 4, fields2.length);
                ;
                data.add(total);
            }
            if (line1 != null && !line1.isBlank()) {
                throw new IOException("Trailing single line: " + line1);
            }
        }
    }
    return data;
}
  • 子字符串比拆分更好、更安全。

  • 而不是 String[] 你可以使用 record class(因为 java 14)

    record Visitor(String no, String date, String name, String address,
            String phone, String birthday, String need) { }
    List<Visitor> data = new ArrayList<>();
    data.add(new Visitor(fields1[0], fields1[1], fields1[2], fields1[3],
        fields2[0], fields2[1], fields2[2]);
    

一个record需要很少的代码,但是不能更改,只能在列表中替换。