开发者

PMD compliant stream copy in java

I have a piece of code for stream copying.

OutputStream os = ...;
InputStream is = ...;
int bufferLength;
byte[] buffer = new byte[1024];
while ((bufferLength = is.read(buffer)) != -1) {
   os.write(buffer, 0, bufferLength);
}

If I run PMD over it, I get the following warning http://pmd.sourceforge.net/rules/controversial.html#AssignmentInOperand.

Now I wish to get rid of that warning, but the only alternative I can think of is something like

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);
}

开发者_如何学运维And I don't really like that because I end up duplicating code. Is there a more elegant way to satisfy this PMD rule?


The most elegant way ... is to suppress the warning.

PMD ships with a lot of rules and the idea is that you select those that you want to use in your own code. If you think, that assignments in operands are OK, simply suppress the warning:

@SuppressWarnings("PMD.AssignementInOperand")

By the way, this is defined in the controversial ruleset anyway. I wouldn't activate that at all.

The Controversial Ruleset contains rules that, for whatever reason, are considered controversial. They are separated out here to allow people to include as they see fit via custom rulesets. This ruleset was initially created in response to discussions over UnnecessaryConstructorRule which Tom likes but most people really dislike :-)

After using PMD for a while, your should start thinking about a custom ruleset that includes all rules and only those rules that you agree on.


I just wanted to advice you to use Commons IO:

IOUtils.copy(is, os);

and then I had a quick look at the source code of copy():

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

I would assume your code is valid and leave it as-is. Or maybe do-while loop will do the trick?


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


Maybe an additional recursive method could solve this warning:

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);
    }
}

Since you have to initialize your buffer with some length I can't see other way around to not duplicate code or use two methods.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜