2014-02-25 33 views
2

我想遍历一个文本文件一次一行,对内容进行操作,并将结果传输到单独的文件。教科书案例BufferedReader.readLine()是否有任何Java流输入库保留行尾字符?

但是:我需要用换行符粘合我的行,以及如果原始文件没有针对我的平台的“正确”换行符(Linux上的DOS文件或反之亦然)会怎么样?我想我可以在流中读一点,看看我找到了什么样的行结尾,尽管这真的很难。

但是:假设我的输入文件没有尾随换行符。我想保留它们的样子。现在我需要向前看到下一行结束,然后每行读取。在这一点上,我为什么要使用一个给我readLine()的类?

这似乎应该是一个解决的问题。有没有一个库(甚至更好,核心的Java7类!),只是让我打电话的方法类似于readLine(),从流中返回一行文本, EOL字符完好无损?

回答

1

下面是由炭炭读取,直到找到一个行结束的实现。通过的读者必须支持mark(),所以如果你的没有,请将其包装在BufferedReader中。

public static String readLineWithTerm(Reader reader) throws IOException { 
    if (! reader.markSupported()) { 
     throw new IllegalArgumentException("reader must support mark()"); 
    } 

    int code; 
    StringBuilder line = new StringBuilder(); 

    while ((code = reader.read()) != -1) { 
     char ch = (char) code; 

     line.append(ch); 

     if (ch == '\n') { 
      break; 
     } else if (ch == '\r') { 
      reader.mark(1); 
      ch = (char) reader.read(); 

      if (ch == '\n') { 
       line.append(ch); 
      } else { 
       reader.reset(); 
      } 

      break; 
     } 
    } 

    return (line.length() == 0 ? null : line.toString()); 
} 
+1

我认为这与我最终构建的实现大致相同,但仍然让人感到困惑,似乎没有人需要这样做! – Coderer

2

更新:

但我需要换行,什么胶水我行在一起,如果原文件没有为我的平台上的Linux“正确的”换行(DOS文件或反之亦然)?我想我可以在流中读一点,看看我找到了什么样的行结尾,尽管这真的很难。

您可以使用指定的字符集创建一个BufferedReader。所以如果文件很古怪,你就得提供文件的字符集。 Files.newBufferedReader(Path p, Charset cs)

是否有一个库(甚至更好,核心Java7一流!),将刚刚 让我叫类似的readLine()返回从流 一行文本的方法,用EOL字符(s)完好无损?

如果你要读一个文件,你必须知道它是什么字符集。如果你知道它是什么字符集,那么你不需要EOL字符是“完整的”,因为你可以将它添加到自己。


BufferedReader.readLine

读取一行文本。换行符被换行符('\ n'),回车符('\ r')或回车符后面的换行符中的任何一个结束。

返回: 包含该行的内容,不包括任何行终止符,或字符串NULL,如果流的末尾已到达

所以BufferedReader.readLine返回任何行终止字符。如果要保留这些字符,则可以使用read方法。

int size = 1000; // size of file 

BufferedReader br = new BufferedReader(new FileReader("file.txt")); 
char[] buf = new char[size]; 
br.read(buf, 0, size); 

这只是一个简单的例子,但如果文件有行终止,那么它将显示在缓冲区中。

+0

也许我需要澄清OP,但我明白BufferedReader中的方法不会做我所需要的。我的意思是,也许有一个Apache Commons库或Guava中更灵活的东西? Ted在正确的轨道上(下方),但我认为我不认为我可以将StreamTokenizer作为标记返回整行(尽管我当然希望被证明是错误的)。 – Coderer

+0

您需要更仔细地重新阅读我的文章。我在BufferedReader中给了你一个方法,**将**做你需要的。你绝对**不需要第三方库来读取文件中的每个字符。这是每种语言都实现的基本I/O操作。 – ktm5124

+0

我的意思是'read()'方法只是图片的一部分。当然,我可以填充一个缓冲区,但是接下来我必须找到结束行,加载更多的数据......现在当我点击缓冲区的末尾时会发生什么?我需要加载更多...但如果一行超过1000个字符呢?等等等等。现在我基本上正在重新实现整个readLine逻辑。这并不是说它很难*或者什么,我只是不想为自己发现所有的边缘情况。这就是为什么我一直在问一个图书馆... – Coderer

0

您应该使用StreamTokenizer来获得对输入速度的更详细的控制。

​​

+0

看起来好像我不得不遍历每一行的“单词”,这与读取像@ ktm5124建议的块一样的东西几乎同样痛苦。我真的想要一个界面,一次给我一行,包括结尾。它看起来像我可能必须建立自己的... – Coderer

+0

我想我上次我做了你在做什么,我最终读取整个文件作为一个字符串,然后使用StringTokenizer(它支持返回分隔符) 。 –

+0

我现在没有这个选项 - 它不是一个文件,它是另一个框架交给我的InputStream。我可以将整个流读入内存,但我不能保证它不会是多个GB。如果可能的话,我真的需要流式处理:( – Coderer

相关问题