Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 873
rompetroll Avatar asked Aug 11 '11 11:08

rompetroll


3 Answers

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.

like image 134
Andreas Dolk Avatar answered Nov 12 '22 01:11

Andreas Dolk


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?

like image 42
Tomasz Nurkiewicz Avatar answered Nov 12 '22 02:11

Tomasz Nurkiewicz


while (true) {
   int bufferLength = is.read(buffer);
   if (bufferLength == -1) 
      break;
   os.write(buffer, 0, bufferLength);
}
like image 1
Thilo Avatar answered Nov 12 '22 01:11

Thilo