store whole InputStream in a String

P

Paul Lutus

Mike said:
No, try it. That loop is entirely correct. Yours only reads from the
stream once.

Yes, thank you, my mistake. Here are the correct versions:

// using while

int len;

while((len = inputStream.read(buffer)) > 0) {
        bout.write(buffer, 0, len);
}

// using for

for(int len;(len = inputStream.read(buffer)) > 0;) {
        bout.write(buffer, 0, len);
}

Again, it is very desirable from a code maintenance standpoint to avoid
duplicate lines of code. The alternatives all seem to duplicate one line,
or use "while(true)", or some other hack.
 
P

Paul Lutus

ak wrote:

/ ...
Summary: Never write two identical lines of code when you can instead write
one.

ok, what is with folowing, also nightmare?

int len;
do {
len = inputStream.read[buffer];
if(len > 0) {
bout.write(buffer, 0, len);
}
}while(len > 0);

Well, it has to test a value twice. This is a bad idea. Avoid duplicate code
lines.
or better:

int len;
do {
len = inputStream.read[buffer];
writeBuffer(buffer, len, bout);
}

No, this never tests "len" for zero, so it runs on foerever after the end of
the file.
private static void writeBuffer(byte [] buffer, int len, OutputStream out)
{
if(len > 0) {
out.write(buffer, 0, len);
}
}

This doesn't solve the problem that the original do-loop doesn't have a
provision to terminate.

All apart from an error I have also been ignoring:

len = inputStream.read[buffer]; -> len = inputStream.read(buffer);
 
P

Paul Lutus

ak said:
int len = inputStream.read[buffer];
while(len > 0) {
bout.write(buffer, 0, len);
len = inputStream.read[buffer];
}

A maintenance nightmare. This is an example of the kind of coding
practice that drives software administrators up the wall. Always avoid
this silly construction, the kind that uses two identical lines of code
to avoid a little thought.

there is nothing wrong if len initialized with same code as incremented.

You have two identical lines in your code. This is a bad idea. Code
administrators try to keep this from happening. It invites errors any time
the code is changed. Also, it makes programs physically longer for no
reason.
even if this one line looks ugly?

It doesn't look ugly after you have seen it ten thousand times. :)
 
B

Ben O'Brien

ak said:
Can I write all contents of an InputStream to a String at once?

something like

String a = inputStream.readAll();

sure:

public String readAll(InputStream inputStream) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte [] buffer = new byte[1024];
while(true) {
int len = inputStream.read[buffer];
if(len < 0) {
break;
}
bout.write(buffer, 0, len);
}
byte [] data = bout.toByteArray();
return new String(data);
}

String a = readAll(in);
Good answer this one, except I must agree with Paul so my answer would be:

public String readAll(InputStream inputStream) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte [] buffer = new byte[1024];
int len;
while(len = inputStream.read(buffer) > 0) {
bout.write(buffer, 0, len);
}
byte [] data = bout.toByteArray();
return new String(data);
}

String a = readAll(in);

IMHO break, continue and goto all make for spaghettified code (aaaah Fortran) that is a bit hard to read sometimes.
My/Paul's version doesn't declare len multiple times either, and it doesn't have the chance writing zero bytes either.
Honestly though, if we were worried about these minimal performance improvements we wouldn't be using Java would we?
Although every little bit helps. Also the buffer size might be tuned a bit, depending on the application I suppose.

Ben.
 
M

Mike Schilling

Paul Lutus said:
Mike Schilling wrote:

This is a programming principle, not a debate about something vague,
something about which there is any dispute. Reliable, maintainable code
doesn't arise by accident.

When making working, readable code more "reliable and maintainable" results
in breaking it, I become skeptical, particularly since it had to be pointed
out to you several times that it was broken. Perhaps it's not as
maintainable as you maintain.
 
M

Mike Schilling

Paul Lutus said:
In any case, writing "while(true)" simply builds a perpetual loop that
requires "break" to terminate, creating the illusion of appropriate usage.


It builds a loop which will be exited from the middle rather than the top or
bottom, which is precisely the case.
 
P

Paul Lutus

Mike said:
It builds a loop which will be exited from the middle rather than the top
or bottom, which is precisely the case.

Precisely what case is that? It is a hack. It uses "while(true)", hack one,
then to repair hack one, it uses "break". Neither is required, and neither
is desirable in a maintainable program that meets structured programming
principles.
 
P

Paul Lutus

Mike said:
When making working, readable code more "reliable and maintainable"
results in breaking it,

Post the evidence, not the assertion. I thought I was the one making
"absolute assertions." Here is the current code:

// using while

int len;

while((len = inputStream.read(buffer)) > 0) {
        bout.write(buffer, 0, len);
}

// using for

for(int len;(len = inputStream.read(buffer)) > 0;) {
        bout.write(buffer, 0, len);
}
I become skeptical, particularly since it had to
be pointed
out to you several times that it was broken. Perhaps it's not as
maintainable as you maintain.

Try to focus on the topic, not an irrelevant digression.
 
M

Mike Schilling

Paul Lutus said:
Post the evidence, not the assertion. I thought I was the one making
"absolute assertions."
Have you forgottne so soon? You improved working code with an infinite loop.
Try to focus on the topic, not an irrelevant digression.

Whether code works is irrelevant to its reliability?
 
M

Mike Schilling

Paul Lutus said:
Precisely what case is that?
The case of a loop which naturally exists in the middle of its bod. It does
something (read from the stream) and, depending on the status of that,
either terminates or does more work and goes around again. Unless you
torture the first part of the body into a single statement, a while(true)
followed by a conditional break is the only way to express that.

It is a hack.

Arguement by assetion 1.
It uses "while(true)", hack one,
then to repair hack one, it uses "break". Neither is required, and neither
is desirable in a maintainable program that meets structured programming
principles.

Argument by assertion 2 (a particularly silly one, as it calls the use of
"break" to exit a loop a "hack".)

"This is the sort of nonsense up with which I will not put" -- Winston
Churchill
 
P

Paul Lutus

Mike said:
The case of a loop which naturally exists in the middle of its bod.

You meant "exits", I presume.
It
does something (read from the stream) and, depending on the status of
that,
either terminates or does more work and goes around again. Unless you
torture ...

And "torture" is not argument by assertion? The construction you are going
on about is very commonly seen in programming practice, in all current
languages.

The algorithm I posted is shorter, clearer, more maintainable and more
consistent with programming standards than the alternatives.
the first part of the body into a single statement,

e.g. do it properly, in the manner recommended by the principles of
structured programming, buy using "while" as it was intended to be used.
And as seen in any number of programs whose designers didn't want the
opprobrium that attends either multiple identical code lines or misuses of
the language.
a while(true)
followed by a conditional break is the only way to express that.

A while(true) followed by break is the sure sign of someone who needs
remedial programming instruction.
Arguement by assetion 1.

No, it is a hack, not an argument by assertion. "while(true)" is a way to
get around the requirement to test something. It is a misuse of "while".
That is a hack.
Argument by assertion 2 (a particularly silly one, as it calls the use of
"break" to exit a loop a "hack".)

That is in fact a hack, as are 99% of the uses of "break", "continue" et.
al..
"This is the sort of nonsense up with which I will not put" -- Winston
Churchill

A revealing argument by someone intent on arguing the substance of an issue.
 
P

Paul Lutus

Mike Schilling wrote:

/ ...
Have you forgottne so soon? You improved working code with an infinite
loop.

Have you forgotten so soon? This has been corrected, see below, and in any
case it doesn't affect the substance of the discussion.

Reading your posts, one wonders whether you really want to discuss the
issue.
Whether code works is irrelevant to its reliability?

For the fifth time:

// using while

int len;

while((len = inputStream.read(buffer)) > 0) {
        bout.write(buffer, 0, len);
}

// using for

for(int len;(len = inputStream.read(buffer)) > 0;) {
        bout.write(buffer, 0, len);
}

You just ran out of excuses for avoiding the errors in your position.
 
A

ak

Paul,

code you write are may be ok, but comments you write are not ok.
Explain me one thing please - if you writing so reliable code,
why your last arachnofillia after click on "Clear file list below"
clears complete File menu?
 
P

Paul Lutus

ak said:
Paul,

code you write are may be ok, but comments you write are not ok.
Explain me one thing please - if you writing so reliable code,
why your last arachnofillia after click on "Clear file list below"
clears complete File menu?

Your statement is false. The Arachnophilia command "clear file list below"
does exactly what it says it does, and nothing else.

What happens when you select a menu item in a GUI program? This action
carries out the command and dismisses the menu itself. This is exactly what
happens when this specific command is issued in Arachnophilia. When you
reopen the menu, the file list has been cleared, as intended.
 
A

ak

Paul Lutus said:
Your statement is false. The Arachnophilia command "clear file list below"
does exactly what it says it does, and nothing else.

What happens when you select a menu item in a GUI program? This action
carries out the command and dismisses the menu itself. This is exactly what
happens when this specific command is issued in Arachnophilia. When you
reopen the menu, the file list has been cleared, as intended.

no, it shows empty menu
 
V

Vincent Lascaux

// using while
int len;
while((len = inputStream.read(buffer)) > 0) {
bout.write(buffer, 0, len);
}

// using for

for(int len;(len = inputStream.read(buffer)) > 0;) {
bout.write(buffer, 0, len);
}

In fact, those two codes look pretty much the same. This is a good
demonstration that while and for can be interchanged.
Since you can do that every time (use a for instead of a while, and a while
instead of a for), we need a "rule" to say when use which. I say that in
this case, since there is no incrementation part in the for loop, we should
use the while.
I make one exception to this rule (but hell... if there were no exception,
it wouldnt be a rule, would it? ;)) for iterators: in java, the
incrementation is done in the first line of the body part of the loop, but I
still use for because I'm used to iterating data structures with a for loop
In any case, the problem with those versions that duplicate one line of
code
is that there is a duplicate line of code, something professional code
administrators try to avoid at all costs.

I can't agree more with you.
The problem with "while(true)" should be obvious to all -- it is a hack,
as
is the use of "break" to get around the original hack.

I would not say that... I understand the necessity to have a loop that
decides to exit in the middle of its body. The condition of your solution
(which is also mine since I do use the same construction when this problem
arise) is not a pure condition: it actually does things, and this may also
be considered as a hack. What if the code we had to launch before the test
was two lines long?
I don't know what I prefer between writing a small function to handle that
(that does the code and return whether there is something to be treated) or
the while(true)/break solution...
 
P

Paul Lutus

ak said:
no, it shows empty menu

If you download the current version of Arachnophilia and use it with the
current JVM, and unless you have mucked up the menus (possible because
Arachnophilia allows the user to modify the menus), your statement is
false.
 
V

Vincent Lascaux

code you write are may be ok, but comments you write are not ok.
Explain me one thing please - if you writing so reliable code,
why your last arachnofillia after click on "Clear file list below"
clears complete File menu?

Hey! But what does it have to do with the topic?
Are you so out of arguments on the subject that you have to look for
mistakes/problems in Paul's code?
 
A

ak

code you write are may be ok, but comments you write are not ok.
Explain me one thing please - if you writing so reliable code,
why your last arachnofillia after click on "Clear file list below"
clears complete File menu?

File menu behavior it pretty strange:
File ist is not not below, it is above.
After open and close some files only file list is present in file menu -
till restart.
 
A

ak

code you write are may be ok, but comments you write are not ok.
Hey! But what does it have to do with the topic?
Are you so out of arguments on the subject that you have to look for
mistakes/problems in Paul's code?

We spoke abot reliable code.
He mean my code are wrong and his code ok.
I brought counter-example.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top