【问题标题】:Check line for unprintable characters while reading text file读取文本文件时检查不可打印字符的行
【发布时间】:2011-09-14 09:06:39
【问题描述】:

我的程序必须逐行读取文本文件。 UTF-8 格式的文件。 我不确定文件是否正确 - 可能包含不可打印的字符。 是否可以在不进入字节级别的情况下对其进行检查? 谢谢。

【问题讨论】:

  • 您要检查单行还是整个文件?
  • 是否保证换行正确?
  • 检查单行。是的,换行符是正确的。
  • 您的意思是不能以特定字体打印的字符吗?任何字体中都有未定义的字符。这可能是一回事。

标签: java file file-io


【解决方案1】:

使用FileInputStream 打开文件,然后使用InputStreamReader 和UTF-8 Charset 从流中读取字符,并使用BufferedReader 读取行,例如通过BufferedReader#readLine,它会给你一个字符串。获得字符串后,您可以检查您认为不可打印的字符。

例如(没有错误检查),使用try-with-resources(在模糊的现代Java版本中):

String line;
try (
    InputStream fis = new FileInputStream("the_file_name");
    InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
    BufferedReader br = new BufferedReader(isr);
) {
    while ((line = br.readLine()) != null) {
        // Deal with the line
    }
}

【讨论】:

  • 或者,少一步,使用 FileReader 打开文件并使用 BufferedReader 读取行。
  • @stviper:现在是 2015 年,我已经更新它以使用 try-with-resources,更加简洁。 :-)
  • @abhisheknaik96:感谢您的编辑,但只有isr 位是正确的; () supposed(),而不是 {},并且最后一个分号不是必需的(但它是允许的,所以我留下了它 - 更符合上面的行)。
【解决方案2】:

虽然使用BufferedReaderInputStreamReader 手动执行此操作并不难,但我会使用Guava

List<String> lines = Files.readLines(file, Charsets.UTF_8);

然后你可以对这些线条做任何你喜欢的事情。

编辑:请注意,这将一次性将整个文件读入内存。在大多数情况下,这实际上很好 - 它肯定比逐行阅读更简单,在阅读时处理每一行。如果它是一个巨大的文件,你可能需要按照 T.J. 那样做。克劳德的回答。

【讨论】:

  • Guava 还提出了一个带有回调 Files.readLines(File file, Charset charset, LineProcessor callback)的方法
  • 如果目的是逐行处理,使用BufferedRead就很简单。在核心 Java 库已经支持的情况下添加另一个库依赖项仅用于行读取也是过大的。
  • @user172818:不,它没有那么简单……至少如果你没有使用 Java 7 和它的 try-with-resources 语句。此外,我对任何在 多个 地方都无法从 Guava 中受益的非平凡 Java 程序感到惊讶。这是一个很棒的图书馆,我不会没有它。
【解决方案3】:

刚刚发现使用 Java NIO (java.nio.file.*) 可以轻松编写:

List<String> lines=Files.readAllLines(Paths.get("/tmp/test.csv"), StandardCharsets.UTF_8);
for(String line:lines){
  System.out.println(line);
}

而不是处理FileInputStreams 和BufferedReaders...

【讨论】:

  • 只想补充一下,java.nio.file.*从JDK 7开始就可以使用了
  • 值得一提的是Files.readAllLines 的文档:此方法适用于在单个操作中方便读取所有行的简单情况。它不适用于读取大文件
  • @fabian 你说得对,我一直在用这个:)
【解决方案4】:

如果要检查字符串是否包含不可打印的字符,可以使用正则表达式

[^\p{Print}]

【讨论】:

  • 然而,这包括非打印字符集中的空格和制表符,它们会影响页面中单词的位置。
【解决方案5】:

下面怎么样:

 FileReader fileReader = new FileReader(new File("test.txt"));

 BufferedReader br = new BufferedReader(fileReader);

 String line = null;
 // if no more lines the readLine() returns null
 while ((line = br.readLine()) != null) {
      // reading lines until the end of the file

 }

来源:http://devmain.blogspot.co.uk/2013/10/java-quick-way-to-read-or-write-to-file.html

【讨论】:

  • 不——删除这个——你正在使用默认编码——进入一个痛苦的世界。
【解决方案6】:

我可以找到以下方法。

private static final String fileName = "C:/Input.txt";

public static void main(String[] args) throws IOException {
    Stream<String> lines = Files.lines(Paths.get(fileName));
    lines.toArray(String[]::new);

    List<String> readAllLines = Files.readAllLines(Paths.get(fileName));
    readAllLines.forEach(s -> System.out.println(s));

    File file = new File(fileName);
    Scanner scanner = new Scanner(file);
    while (scanner.hasNext()) {
        System.out.println(scanner.next());
    }

【讨论】:

    【解决方案7】:

    @T.J.Crowder 的答案是 Java 6 - 在 java 7 中,有效的答案是 @McIntosh 的答案 - 尽管不鼓励使用 Charset 作为 UTF -8 的名称:

    List<String> lines = Files.readAllLines(Paths.get("/tmp/test.csv"),
        StandardCharsets.UTF_8);
    for(String line: lines){ /* DO */ }
    

    提醒了上面 Skeet 发布的很多番石榴方式 - 当然同样的警告也适用。也就是说,对于大文件(Java 7):

    BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
    for (String line = reader.readLine(); line != null; line = reader.readLine()) {}
    

    【讨论】:

    • 对 Java 6 有效的答案对 Java 7 仍然有效。
    • @user207421 当有更好的方法时不是真的
    【解决方案8】:

    如果文件中的每个字符都以 UTF-8 正确编码,则使用 UTF-8 编码的阅读器读取它不会有任何问题。由您来检查文件的每个字符,看看您是否认为它可打印。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 2019-01-29
      • 2021-12-20
      • 1970-01-01
      相关资源
      最近更新 更多