Java中符合PMD标准的流复制

5
我有一段关于流复制的代码。
OutputStream os = ...;
InputStream is = ...;
int bufferLength;
byte[] buffer = new byte[1024];
while ((bufferLength = is.read(buffer)) != -1) {
   os.write(buffer, 0, bufferLength);
}

如果我在它上面运行PMD,我会得到以下警告:http://pmd.sourceforge.net/rules/controversial.html#AssignmentInOperand
现在我希望消除这个警告,但是我能想到的唯一替代方案是类似于:
OutputStream os = ...;
InputStream is = ...;
int bufferLength;
byte[] buffer = new byte[1024];
bufferLength = is.read(buffer);
while (bufferLength != -1) {
   os.write(buffer, 0, bufferLength);
   bufferLength = is.read(buffer);
}

我不太喜欢这种方式,因为这样会导致代码重复。有没有更优雅的方法来满足这个PMD规则?


你可以使用Commons IO来避免重复代码 :-) - Thilo
4个回答

4

最优雅的方式是抑制警告。

PMD随附了许多规则,其想法是您可以选择在自己的代码中使用的规则。如果你认为操作数中的赋值是可以接受的,那么只需抑制警告即可:

@SuppressWarnings("PMD.AssignementInOperand")

顺便提一句,这在“有争议的规则集”中已经定义好了。我根本不会激活它。
“有争议的规则集”包含被认为有争议的规则。它们被单独分离出来,以允许人们通过自定义规则集进行包含。这个规则集最初是为了回应UnnecessaryConstructorRule的讨论而创建的,Tom喜欢但大多数人真的不喜欢:-)
使用PMD一段时间后,您应该考虑一个自定义规则集,其中包括所有规则和仅您同意的规则。

是的,我理解这个规则是有争议的。但实际上,如果你不经常看到类似的<赋值运算符>结构,阅读起来可能会有些困难,我同意这一点。 - rompetroll
1
正确。但是你的例子展示了一个非常常见的模式,抑制警告是有意义的。在其他情况下,我同意,警告会帮助提高意识,让人们知道代码很难理解。 - Andreas Dolk

3

我建议您使用Commons IO库:

IOUtils.copy(is, os);

然后我快速查看了copy()的源代码:

byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int n = 0;
while (-1 != (n = input.read(buffer))) {
    output.write(buffer, 0, n);
}

我认为你的代码是有效的,可以保留它原来的形式。或者使用 do-while 循环语句也可以解决问题?

1
while (true) {
   int bufferLength = is.read(buffer);
   if (bufferLength == -1) 
      break;
   os.write(buffer, 0, bufferLength);
}

0
也许可以通过添加一个递归方法来解决这个警告:
private static void writeToInputStream(final InputStream is, final OutputStream os) throws IOException {
    writeToInputStream(is, os, new byte[8388608]); // 8388608 bits = 1024 * 1024 * 8 = 1MB
    os.flush();
}

private static void writeToInputStream(final InputStream is, final OutputStream os, final byte[] dados) throws IOException {
    final int read = is.read(dados, 0, dados.length);
    if (read != -1) {
        os.write(dados, 0, read);
        writeToInputStream(is, os, dados);
    }
}

因为你必须使用一些长度来初始化你的缓冲区,我看不到其他方法可以避免重复代码或使用两个方法。


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