提问人:Fizzmaister 提问时间:12/1/2011 更新时间:12/20/2022 访问量:29208
Java 扫描程序未遍历整个文件
Java scanner not going through entire file
问:
我正在用 Java 编写一个程序,我需要做的一件事是为最短路径问题创建一组每个有效位置。这些位置在遵循严格模式(每行一个条目,没有额外空格)的 .txt 文件中定义,非常适合使用 .nextLine 获取数据。我的问题是,文件中的 241 行(共 432 行)扫描仪在条目的 3/4 处停止工作,并且无法识别任何新行。
我的代码:
//initialize state space
private static Set<String> posible(String posLoc) throws FileNotFoundException {
Scanner s = new Scanner(new File(posLoc));
Set<String> result = new TreeSet<String>();
String availalbe;
while(s.hasNextLine()) {
availalbe = s.nextLine();
result.add(availalbe);
}
s.close();
return result;
}
数据
Shenlong Gundam
Altron Gundam
Tallgee[scanner stops reading here]se
Tallgeese II
Leo (Ground)
Leo (Space)
当然,“扫描仪在此处停止读取”不在数据中,我只是标记扫描仪停止读取文件的位置。这是文件中的 3068 字节,但这不应该影响任何事情,因为在同一个程序中,使用几乎相同的代码,我正在读取一个 261 行、14KB .txt的文件,该文件对路径进行编码。任何帮助将不胜感激。
谢谢。
答:
扫描仪读取您的文件有问题,但我不确定它是什么。它错误地认为它已经到达了文件的末尾,而实际上还没有,这可能是由于一些时髦的字符串编码。请尝试改用包装 FileReader 对象的 BufferedReader 对象。
例如,
private static Set<String> posible2(String posLoc) {
Set<String> result = new TreeSet<String>();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File(posLoc)));
String availalbe;
while((availalbe = br.readLine()) != null) {
result.add(availalbe);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
编辑:我尝试将您的问题减少到最低限度,这足以引发问题:
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(new File(FILE_POS));
int count = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.printf("%3d: %s %n", count, line );
count++;
}
我用 printf 检查了 Scanner 对象:
System.out.printf("Str: %-35s size%5d; Has next line? %b%n", availalbe, result.size(), s.hasNextLine());
并表明它认为文件已经结束。我正在逐步删除从数据到文件的行,以查看是哪一行导致了问题,但会把它留给你。
评论
我遇到了同样的问题。扫描仪不会读取到文件的末尾,实际上会停在单词的中间。我认为这是扫描仪上设置的某些限制的问题,但我注意到了 rfeak 关于字符编码的评论。
我重新保存了我正在阅读的内容,它解决了问题。事实证明,记事本默认为 ANSI。.txt
UTF-8
你应该使用这个:
扫描程序扫描程序 = new Scanner(fileObj).useDelimiter(“\z”);
System.out.println(scanner.next());
评论
我遇到了同样的问题,这就是我为解决它所做的:
- 将我正在读取的文件保存到 UTF-8 中
- 创建了新的扫描仪,如下所示,指定编码类型:
Scanner scanner = new Scanner(new File("C:/IDSBRIEF/GuidData/"+sFileName),"UTF-8");
评论
我有一个 txt 文件,其中 Scanner 在第 862 行停止读取,这是一个奇怪的问题。我所做的是创建一个不同的文件(以尝试复制问题)。我先添加了不到 862 行,然后我添加了超过 862 行,效果很好。
所以我认为问题在于,在我之前的文件中,在第 862 行,出现了一些问题,比如某些字符或符号可能会误导 Scanner 提前完成阅读。
总之:基于这一经验,我建议找出扫描仪停止读取的确切行,以找到解决问题的方法。
我的具体情况:
- 在我的主程序 (A) 中,它总是从 16384 字节文件中读取 41021 字节。它停止的字符位于具有正常可打印文本的行的中间
- 如果我创建一个只有扫描仪和打印行的小型单独程序 (B),它会读取整个文件
- 在 (A) 中指定“UTF-8”仍显示为 16384
- 在 (A) 中指定“ASCII”仍为 16384
- 在 (A) 中指定“Cp1252”将读取整个文件
- 我的输入 txt 文件是由用户发送的,我不确定他们是否会以任何特定的编码编写它们
结论
- Scanner 似乎逐块读取文件并将正确读取的数据写入返回的 String 中,但是当它发现编码与预期不同的块时,它会静默退出(哎哟)并返回部分字符串
- 我尝试读取的 txt 文件是 Cp1252,我的 (A) 源文件是 UTF-8,我的 (B) 源文件是 Cp1252,所以这就是为什么 (B) 在不指定编码的情况下工作的原因
溶液
- 忘记扫描仪并使用
String fullFileContents = new String(Files.readAllBytes(myFile.toPath()));
当然,由于您不知道编码,因此无法像这样可靠地读取非 ASCII 字符,但肯定会读取 ASCII 字符。如果您只需要文件中的 ASCII 字符并且可以丢弃非 ASCII 部分,请使用它。
评论
new String(bytes, StandardCharsets.US_ASCII)
new String(bytes)
我在我的 Linux 服务器上也遇到了类似的问题,最后下面的代码对我有用。
Scanner scanner = new Scanner(new File(filename),“UTF-8”);
我在 csv 文件上遇到了同样的问题:它可以在 Windows 上运行,但在 Linux 上不起作用
使用 nodepad++ 打开文件并更改编码,选择 : Encode in UTF8 (with BOM)。 它解决了我的问题
这是我倾向于做的:
StringBuilder fileContents = new StringBuilder();
File file = new File(Location);
try (BufferedReader reader = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
fileContents.append(line);
fileContents.append(System.lineSeparator());
}
}
String outcome = fileContents.toString();
我接管了一个 4MB 奇怪的 CSV 文件,该文件在多个地方抛出读取错误:
1.在 Cp1252 中打开文件
2.立即将其以UTF-8保存在第二个文件中
- 现在在第二个文件上调用您扫描仪。
评论