使用Scanner读取一行

40

编辑:针对后来的读者,问题是我的输入文件已损坏。

我不明白我做错了什么:

我正在使用这段代码:

    File f = new File("C:\\Temp\\dico.txt");
    BufferedReader r = null;
    try {
        r = new BufferedReader(new FileReader(f));
        String scan;
        while((scan=r.readLine())!=null) {
            if(scan.length()==0) {continue;}
            //treatment
        }
    } catch (FileNotFoundException ex) {
        Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        if(r!=null) try {
            r.close();
        } catch (IOException ex) {
            Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

现在这段代码已经很好地运作了。不过,出于某种原因,我希望更换一个Scanner。我的代码变成了:

    File f = new File("C:\\Temp\\dico.txt");
    Scanner r = null;
    try {
        r = new Scanner(f);
        String scan;
        while(r.hasNextLine()) {
            scan = r.nextLine();
            if(scan.length()==0) {continue;}
            //treatment
        }
    } catch (FileNotFoundException ex) {
        Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        if(r!=null) r.close();
    }

这一次,我们从未进入 while 循环,因为 r.hasNextLine() 总是返回“false”。你有什么想法,我错在哪里了吗?

我要明确的是,除此之外没有任何变化,文件仍然是原来的那个。

编辑:我也要明确的是,我尝试使用另一个文件得到了相同的结果,这意味着问题似乎不是来自文件。

文件长成这样:

a
à
abaissa
abaissable
abaissables
abaissai
abaissaient
abaissais
abaissait
...
编辑2: 由于问题只在我将文件内容从我的文件复制/粘贴到另一个文件时才出现,因此文件的内容似乎存在问题。换句话说,如果我自己编写内容,则可以正常工作;如果我使用dico.txt文件中的一部分内容,则无法正常工作。有什么解释吗? 编辑3: 这些是我的文件链接。我建议您避免使用非常庞大的dico.txt。
dico.txt:https://drive.google.com/file/d/0B0sroFy9HZlBNDl3MUwzVnh6VU0/edit?usp=sharing test.txt:https://drive.google.com/file/d/0B0sroFy9HZlBemZjbXU1RmlmdjQ/edit?usp=sharing

你能展示一下 dico.txt 文件吗? - Alexis C.
我编辑了我的问题并包含了它。但是,为什么 BufferedReader 能够正确读取行而 Scanner 却不能呢?我在初始化时错过了什么吗? - Sharcoux
5个回答

28

这段代码逐行读取文件。

public static void readFileByLine(String fileName) {
  try {
   File file = new File(fileName);
   Scanner scanner = new Scanner(file);
   while (scanner.hasNext()) {
    System.out.println(scanner.next());
   }
   scanner.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } 
 }

您还可以将分隔符设置为换行符,然后执行相同的操作。

 scanner.useDelimiter(System.getProperty("line.separator"));
你需要检查是否有下一个可用的token,然后读取下一个token。您还需要仔细检查Scanner所接收到的输入,即dico.txt文件。默认情况下,Scanner根据空格进行输入分割。请确保输入中的定界符位置正确。
a
à
abaissa
abaissable
abaissables
abaissai
abaissaient
abaissais
abaissait

我尝试使用以下代码来阅读它,结果一切正常。

 File file = new File("/home/keerthivasan/Desktop/input.txt");
     Scanner scr = null;
         try {
            scr = new Scanner(file);
            while(scr.hasNext()){
                System.out.println("line : "+scr.next());
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ScannerTest.class.getName()).log(Level.SEVERE, null, ex);
        }

输出:

line : a
line : à
line : abaissa
line : abaissable
line : abaissables
line : abaissai
line : abaissaient
line : abaissais
line : abaissait

所以,我确信这应该会起作用。由于您在Windows环境下工作,因此行尾(EOL)序列(0x0D 0x0A,\r\n)实际上是两个ASCII字符,即CR和LF字符的组合。如果您将Scanner实例设置为使用以下分隔符,它可能会拾取到:

 scr = new Scanner(file);
 scr.useDelimiter("\r\n");

然后进行循环以读取每一行。希望这可以帮到你!


我尝试了\n、\r和\r\n,但没有结果。很抱歉我是个新手,但我怎么知道编码方式呢?无论如何,我一直在使用记事本工作。你想让我做什么?我已经从dico.txt复制到test.txt,但效果并不好(参见我的第二次编辑)。 - Sharcoux
你能提供一个文件链接吗?我可以看一下。由于你正在使用Windows环境,请尝试在命令提示符中打开该文件。你使用的是哪个操作系统版本? - Keerthivasan
你可以使用Notepad++或PSPad查看特殊字符和EOL字符,并尝试删除不必要的字符。 - Keerthivasan
1
你的dico.txt文件已经损坏。我刚刚将它重新编码为UTF-8格式,我的代码可以完美地运行。我正在上传新文件,并分享链接 - https://drive.google.com/file/d/0B-0YRK_ObuLVUUozV29fdmhqaVU/edit?usp=sharing 请从现在开始使用这个文件。请告诉我发生了什么事。 - Keerthivasan
1
@megido 你是对的。但是,这个需求每行只有一个单词。所以它可以工作。 - Keerthivasan
显示剩余11条评论

7

next()和nextLine()方法都与Scanner有关,用于获取字符串输入。它们的区别在于...

next()仅能读取空格之前的输入内容,无法读取由空格隔开的两个单词。此外,next()读取完输入内容后,将光标置于同一行。

nextLine()读取包括单词间的空格在内的所有输入内容(即,直到读取到换行符\n为止)。输入完成后,nextLine()将光标定位于下一行。

阅读文章:区分next()和nextLine()

请使用以下语句替换您的while循环:

while(r.hasNext()) {
                scan = r.next();
                System.out.println(scan);
                if(scan.length()==0) {continue;}
                //treatment
            }

使用hasNext()next()方法可以解决这个问题。

我的端口没有返回false。 - Nishant Lakhara
我把文件放在了我的第三个版本上。你能试试这些文件吗?看起来问题是源自于文件内容。感谢你的帮助。 - Sharcoux
我无法访问Google Drive。请发邮件至nishu.lakhara.28@gmail.com与我联系。 - Nishant Lakhara
谢谢您的帮助。该文件已经损坏。问题已由Keerthi Ramanathan解决。 - Sharcoux

1
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication1;

import java.io.File;
import java.util.Scanner;

/**
 *
 * @author zsagga
 */
class openFile {
        private Scanner x ; 
        int count = 0 ; 
        String path = "C:\\Users\\zsagga\\Documents\\NetBeansProjects\\JavaApplication1\\src\\javaapplication1\\Readthis.txt"; 


    public void openFile() {
//                System.out.println("I'm Here");
        try {
            x = new Scanner(new File(path)); 

        } 
        catch (Exception e) {
            System.out.println("Could not find a file");
        }
    }

    public void readFile() {

        while (x.hasNextLine()){
            count ++ ;
            x.nextLine();     
        }
        System.out.println(count);
    }

    public void closeFile() {
        x.close();
    }
}

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication1;

/**
 *
 * @author zsagga
 */
public class JavaApplication1 {

    public static void main(String[] args) {
        // TODO code application logic here
        openFile r =  new openFile(); 
        r.openFile(); 
        r.readFile();
        r.closeFile(); 

    }
}

1

对于那些仍然无法使用Java扫描器读取简单的.txt文件的人。


我遇到了一个问题,即扫描仪无法读取下一行,当我复制和粘贴信息时,或者我的文件中有太多文本时。
解决方法是:将您的 .txt 文件编码为 UTF-8。这可以通过重新打开文件并将编码更改为 UTF-8 来简单地完成。(在 Win7 中,在右下角附近)
此后,扫描仪不应该有任何问题。

Scanner scanner = new Scanner(new File(csvFile), "Windows-1250"); - Jarda Pavlíček

0
尝试使用 r.hasNext() 而不是 r.hasNextLine():
while(r.hasNext()) {
        scan = r.next();

r.hasNext()让我进入了循环,但问题是r.nextLine()抛出了java.util.NoSuchElementException: No line found。 - Sharcoux
抱歉,实际上 r.hasNext() 也返回 false... 我不明白出了什么问题。 - Sharcoux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接