逐行迭代文本文件的内容 - 是否有最佳实践?(与PMD的AssignmentInOperand相比)

Ron*_*onK 38 java pmd while-loop

我们有一个Java应用程序,它有一些知道读取文本文件的模块.他们非常简单地使用这样的代码:

BufferedReader br = new BufferedReader(new FileReader(file));  
String line = null;  
while ((line = br.readLine()) != null)  
{  
   ... // do stuff to file here  
} 
Run Code Online (Sandbox Code Playgroud)

我在我的项目上运行PMD并在线路上获得了" AssignmentInOperand "违规while (...).

除了显而易见的事情之外,是否有更简单的方法来执行此循环:

String line = br.readLine();  
while (line != null)  
{  
   ... // do stuff to file here  
   line = br.readLine();  
} 
Run Code Online (Sandbox Code Playgroud)

这被认为是更好的做法吗?(虽然我们"复制" line = br.readLine()代码?)

Leo*_*lla 33

我知道这是一个老帖子,但我只是有相同的需求(差不多),我使用Apache Commons中的FileUtils中的LineIterator来解决它.从他们的javadoc:

LineIterator it = FileUtils.lineIterator(file, "UTF-8");
try {
    while (it.hasNext()) {
    String line = it.nextLine();
    // do something with line
    }
} finally {
    it.close();
}
Run Code Online (Sandbox Code Playgroud)

查看文档:http: //commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/LineIterator.html


Jon*_*eet 21

我通常更喜欢前者.我不通常喜欢的比较中的副作用,但这个特定的例子是一个成语,其是如此普遍和如此方便,我不反对.

(在C#中有一个更好的选项:返回一个IEnumerable<string>你可以用foreach迭代的方法;这在Java中不那么好,因为在增强的for循环结束时没有自动处理...还因为你不能IOException从迭代器中抛出,这意味着你不能只为另一个替换它.)

换句话说:重复行问题比操作中的赋值问题困扰我.我习惯于一眼就看到这种模式 - 我需要停止重复的线条版本并检查所有内容是否在正确的位置.这可能和其他事情一样习惯,但我不认为这是一个问题.


Aks*_*ert 21

为支持lambda表达式中的Java-8和尝试,利用国际资源的Java 7的让你才达到你在更紧凑的语法想要什么.

Path path = Paths.get("c:/users/aksel/aksel.txt");

try (Stream<String>  lines = Files.lines(path)) {
    lines.forEachOrdered(line->System.out.println(line));
} catch (IOException e) {
    //error happened
}
Run Code Online (Sandbox Code Playgroud)

  • 也可以将lambda缩短为方法引用:`lines.forEachOrdered(System.out :: println)` (2认同)

rol*_*lfl 17

我经常使用这个while((line = br.readLine()) != null)构造......但是,最近我遇到了这个不错的选择:

BufferedReader br = new BufferedReader(new FileReader(file));

for (String line = br.readLine(); line != null; line = br.readLine()) {
   ... // do stuff to file here  
}
Run Code Online (Sandbox Code Playgroud)

这仍然是复制readLine()调用代码,但逻辑清晰,等等.

另一次我使用while(( ... ) ...)构造时是从流中读取byte[]数组...

byte[] buffer = new byte[size];
InputStream is = .....;
int len = 0;
while ((len = is.read(buffer)) >= 0) {
    ....
}
Run Code Online (Sandbox Code Playgroud)

这也可以转换为for循环:

byte[] buffer = new byte[size];
InputStream is = .....;
for (int len = is.read(buffer); len >= 0; len = is.read(buffer)) {
    ....
}
Run Code Online (Sandbox Code Playgroud)

我不确定我是否真的更喜欢for-loop替代品....但是,它将满足任何PMD工具,并且逻辑仍然清晰,等等.