逐字读取文件,扫描仪

Posted

技术标签:

【中文标题】逐字读取文件,扫描仪【英文标题】:Read file by word, Scanner 【发布时间】:2018-03-18 04:40:57 【问题描述】:

我有一个txt文件,其中每一行包含两个单词,例如:

USA 321
France 1009
...
Germany 902

如何在二维数组中逐字读取此文件?我有:

List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);

while (dataScanner.hasNextLine()) 
    Scanner rowScanner = new Scanner(dataScanner.nextLine());
    temps.add(new ArrayList<>(2));

    while (rowScanner.hasNextLine()) 
        ...
    

【问题讨论】:

你必须使用扫描仪的行吗?如果没有,请使用String.split() 将行拆分为单词。 如果你必须对行使用扫描器,不要使用rowScanner.hasNextLine();它只包含一行。使用hasNext()(和next())从行中获取单个单词。此外,如果您确定每行总是正好有 2 个单词,您可以将结构设为 List&lt;String[2]&gt; 【参考方案1】:

假设您的代码有效,我会这样做

List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);

while (dataScanner.hasNextLine()) 
    String[] data = dataScanner.nextLine().split(" ");
    temps.add(new ArrayList<>(Arrays.asList(data[0],data[1]));

这将获取当前行并将其拆分为空格字符。 然后它会创建一个包含这两个元素的列表并将其添加到您的临时列表中

【讨论】:

【参考方案2】:

如果你想绝对使用扫描仪:

List<List<String>> temps = new ArrayList<>();
        Scanner dataScanner = new Scanner("a b\nc d\ne f\n");

        while (dataScanner.hasNextLine()) 
            Scanner rowScanner = new Scanner(dataScanner.nextLine());
            List<String> datas=new ArrayList<>(2);
            temps.add(datas);

            while (rowScanner.hasNext("[^\\s]+")) 
                datas.add(rowScanner.next("[^\\s]+"));
            
        

【讨论】:

【参考方案3】:

我的建议是始终在不同的功能中分离不同的功能。代码变得更易于阅读、更易于维护可重用

public static List<String> readFileLineByLine(String file) 
   List<String> lines = new ArrayList<>();
   Scanner scanner = new Scanner(file);
   while (scanner.hasNextLine()) 
      temps.add(scanner.nextLine());
   
   return lines;


public static List<MyData> parseLines(List<String> lines) 
   List<MyData> list = new ArrayList<>();
   for (String line : lines) 
      String[] data = line.split(" ");
      list.add(new MyData(data[0], data[1]));
   
   return list;

(如果需要,请使用List&lt;String&gt; 作为MyData

【讨论】:

同意你的看法。在你的代码中,我应该添加一个函数来只读取一个 MyData 以增加可维护性和可重用性【参考方案4】:

我是 Scanner 的忠实粉丝,但在这种情况下,您可以通过逐行阅读并使用 String.split 来获得。使用流这变得非常简单。如果你想读入一个二维数组,你可以这样做:

    try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) 
        String[][] result = lines.map(s -> s.split("\\s+"))
                                 .toArray(String[][]::new);
    

或者如果你想要嵌套列表,你可以这样做:

    try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) 
        List<List<String>> result = lines.map(s -> s.split("\\s+"))
                                         .map(Arrays::asList)
                                         .collect(toList());
        System.out.println(result);
    

【讨论】:

以上是关于逐字读取文件,扫描仪的主要内容,如果未能解决你的问题,请参考以下文章

如何从文件中逐字读取?

从文件逐字读取并确定换行 C++

C++ 从文本文件中逐字读取单词或逐字符读取单词

如何逐字读取文件并将这些单词分配给结构? [复制]

如何逐字处理从 SQL 读取的字符串?

Python读取PDF文件[重复]