You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java读取制表符分隔文件至ArrayList,仅读取首行问题求助

问题描述

我正在做一个学校的Java项目,需要读取文本文件中的所有内容并存储到ArrayList中。文本文件内容以制表符分隔,样本如下:

1876    Gore    Vidal   Random House    4/11/1976   Fiction
23337   Stephen King    Scribner    11/27/2011  Fiction
...and Ladies of the Club   Helen Hooven    Santmeyer   Putnam  7/8/1984    Fiction
1st to Die  James   Patterson   Little, Brown   3/25/2001   Fiction
2nd Chance  James   Patterson   Little, Brown   3/24/2002   Fiction
3rd Degree  James   Patterson   Little, Brown   3/21/2004   Fiction
4th of July James   Patterson   Little, Brown   5/22/2005   Fiction

目前我的代码仅能读取第一行内容,无法处理全部数据。现有代码如下:

public static void main(String[] args) throws Exception {
    try {
        FileInputStream fstream = new FileInputStream("bestsellers.txt");
        BufferedReader buf = new BufferedReader(new InputStreamReader(fstream));
        ArrayList<String> words = new ArrayList<>();
        String lineJustFetched = null;
        String[] wordsArray;
        Book CurrentBook = new Book();
        while (true) {
            lineJustFetched = buf.readLine();
            if (lineJustFetched == null) {
                break;
            } else {
                wordsArray = lineJustFetched.split("\t");
                for (String each : wordsArray) {
                    if (!"".equals(each)) {
                        words.add(each);
                    }
                }
            }
        }
        CurrentBook.title = words.get(0);
        CurrentBook.authorFirstName = words.get(1);
        CurrentBook.authorLastName = words.get(2);
        CurrentBook.publisher = words.get(3);
        CurrentBook.category = words.get(5);
        CurrentBook.date = words.get(4);
        buf.close();
        System.out.println("Author's first name is: " + CurrentBook.authorFirstName);
        System.out.println("Author's last name is: " + CurrentBook.authorLastName);
        System.out.println("Title is: " + CurrentBook.title);
        System.out.println("The publisher is: " + CurrentBook.publisher);
        System.out.println("The category is: " + CurrentBook.category);
        System.out.println("The date is: " + CurrentBook.date);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

当前输出仅显示第一本书的信息:

Author's first name is: Gore
Author's last name is: Vidal
Title is: 1876
The publisher is: Random House
The category is: Fiction
The date is: 4/11/1976

我需要读取、存储并输出文件中所有书籍的信息,请求解决该问题。

问题分析

原代码的核心问题:

  • 仅创建了一个Book对象,且在循环结束后才赋值,加上所有行的字段都被塞进同一个ArrayList<String>,最后取索引0-5只会拿到第一本书的信息
  • 错误地将所有行的字段合并存储,无法区分不同书籍的字段边界
修正方案

需要创建ArrayList<Book>存储所有书籍对象,每读取一行文本就解析为一个新的Book实例并添加到列表,最后遍历列表输出所有信息。

修正后的代码

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

// 补充Book类定义(如果项目中已存在可忽略)
class Book {
    String title;
    String authorFirstName;
    String authorLastName;
    String publisher;
    String date;
    String category;
}

public class BookReader {
    public static void main(String[] args) {
        // 使用try-with-resources自动关闭流,避免资源泄漏
        try (FileInputStream fstream = new FileInputStream("bestsellers.txt");
             BufferedReader buf = new BufferedReader(new InputStreamReader(fstream))) {

            ArrayList<Book> booksList = new ArrayList<>();
            String lineJustFetched;

            while ((lineJustFetched = buf.readLine()) != null) {
                // 按制表符拆分每行,过滤首尾空白
                String[] wordsArray = lineJustFetched.trim().split("\t");
                // 跳过格式不正确的行,避免索引越界
                if (wordsArray.length < 6) {
                    continue;
                }

                Book currentBook = new Book();
                // 按文件字段顺序赋值
                currentBook.title = wordsArray[0].trim();
                currentBook.authorFirstName = wordsArray[1].trim();
                currentBook.authorLastName = wordsArray[2].trim();
                currentBook.publisher = wordsArray[3].trim();
                currentBook.date = wordsArray[4].trim();
                currentBook.category = wordsArray[5].trim();

                booksList.add(currentBook);
            }

            // 遍历输出所有书籍信息
            for (int i = 0; i < booksList.size(); i++) {
                Book book = booksList.get(i);
                System.out.println("=== 第" + (i+1) + "本书 ===");
                System.out.println("作者名: " + book.authorFirstName);
                System.out.println("作者姓: " + book.authorLastName);
                System.out.println("书名: " + book.title);
                System.out.println("出版社: " + book.publisher);
                System.out.println("分类: " + book.category);
                System.out.println("出版日期: " + book.date);
                System.out.println();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键改进点

  1. 使用try-with-resources自动管理流资源,无需手动调用close()
  2. 用ArrayList<Book>存储所有书籍,每行对应一个独立的Book实例
  3. 增加格式校验,跳过空行或字段不足的行,避免索引越界异常
  4. 对每个字段调用trim(),清理首尾空白字符
  5. 循环结束后遍历列表,输出全部书籍信息

预期输出

=== 第1本书 ===
作者名: Gore
作者姓: Vidal
书名: 1876
出版社: Random House
分类: Fiction
出版日期: 4/11/1976

=== 第2本书 ===
作者名: Stephen
作者姓: King
书名: 23337
出版社: Scribner
分类: Fiction
出版日期: 11/27/2011

=== 第3本书 ===
作者名: Helen
作者姓: Hooven
书名: ...and Ladies of the Club
出版社: Santmeyer
分类: Fiction
出版日期: 7/8/1984

...(后续书籍信息依次输出)

内容的提问来源于stack exchange,提问作者Dominion oladejo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:15:18