Live data from Hacker News

Copying stdin to stdout in Java

gist.github.com

41–50 of 61 posts

Re: Copying stdin to stdout in Java

#41

I don't have the post context, but at 13 lines, I feel even something like Go wouldn't even be considerably larger or marginally easier to understand.

It's not much shorter, but it was pretty easy to write it you know the libraries. package main import ("os"; "io") func main() { io.Copy(os.Stdout, os.Stdin) }

The order of os.Stdout, os.Stdin is interesting. I'd assume src->dest being more intuitive order.

Any ideas if this destBy the way, Pipe in the same package is the other way around: (PipeReader, PipeWriter)

Re: Copying stdin to stdout in Java

#42
post #6
post #5

Earlier quoted context omitted.

"Why I like Java" by Mark Dominus: https://news.ycombinator.com/item?id=7463671

Who never wrote it but assumed we know that the same program in Perl, without using command line switches is while ( ) { print; } Still Awk is shorter: { print } And if you are allowed change the switches of the command line to Perl for your program that Perl program can have exactly 0 bytes .

grep is even shorter:

    grep $
That reads lines from stdin and echoes to stdout.

Re: Copying stdin to stdout in Java

#43
post #41

Earlier quoted context omitted.

It's not much shorter, but it was pretty easy to write it you know the libraries. package main import ("os"; "io") func main() { io.Copy(os.Stdout, os.Stdin) }

The order of os.Stdout, os.Stdin is interesting. I'd assume src->dest being more intuitive order. Any ideas if this dest By the way, Pipe in the same package is the other way around: ( PipeReader, PipeWriter)

Channels in go use the exact syntax you mention (dst <- src). With this in mind, the argument order of io.Copy is consistent, as well as io.Pipe. You read from a reader - the output of the pipe, and write to a writer - the input of the pipe.

Re: Copying stdin to stdout in Java

#44
The essence of the argument here is that Java is a poor language as it doesn't offer simple abstraction to copy standard input into standard output; that Java is too verbose and low-level for the task.

The lack of direct abstraction is not a valid argument, because as a programmer, you shouldn't be writing the logic in Java, Python, C or Scala but rather a higher order domain language implemented in the chosen host language and that's what the process of programming is all about. For the majority of real world programming tasks it's unlikely that a language that fits the domain perfectly already exist, so you have to create one.

In Java one can say:

    copyStream(System.in,System.out);
And then one will have to implement copyStream but only once:

    long copyStream (InputStream src,OutputStream dst) throws IOException {             
        long bytesCopied;
        byte[] buffer = new byte[8192];
        int bytesRead = src.read(buffer);        

        while(bytesRead!=-1) {
            bytesCopied+=bytesRead;
            dst.write(buffer, 0, bytesRead);
            bytesRead = src.read(buffer);
        }

        return bytesCopied;
    }
I prefer programmers taking this approach of implementing domain specific language first and then expressing the logic in its terms instead of trying to express higher order concepts without resorting to available host language abstractions.

Let's say Python or Perl let one express stream copying more concisely straight out of the box. However when faced with real life programming challenges one will very quickly encounter limits of what a language can express out of the box with one-liner. But as a programmer one has the power to create one-liners from scratch!

Disclaimer: I am not a Java expert, so the code above is just to illustrate the idea based on my very limited knowledge of Java.

Re: Copying stdin to stdout in Java

#45
post #41

Earlier quoted context omitted.

It's not much shorter, but it was pretty easy to write it you know the libraries. package main import ("os"; "io") func main() { io.Copy(os.Stdout, os.Stdin) }

The order of os.Stdout, os.Stdin is interesting. I'd assume src->dest being more intuitive order. Any ideas if this dest By the way, Pipe in the same package is the other way around: ( PipeReader, PipeWriter)

memcpy() and strcpy() and a whole bunch of functions inspired by them have take (dest, source). Maybe it's not theoretically superior, but it is familiar to a whole lot of programmers.

Re: Copying stdin to stdout in Java

#46
post #25

As he notes in the comments, you'd really just do this: IOUtils.copy(System.in, System.out); using the Apache Commons library. That's the most apples-to-apples comparison to more "scripty" languages that have more stuff built in. With Java you pick the libraries/frameworks you want to use. Commons and Guava are extremely popular and robust libraries and really should be included in any comparison against "real world"…

That's right, but it seems like it's fashionable to bash Java inventing example code that noone uses in prodcution. If I would see the code like this, I would ask the one that has written it to justify why he didn't just use IOUtils.copyStream method. Is there some performance reason he wanted to specify buffer size manually? Maybe he wanted to handle exceptions properly instead of wiling silently? Or he was on extremely constrained device where he couldn't afford to include 40k library and just copied the only method he needs instead?

Re: Copying stdin to stdout in Java

#48
post #25

As he notes in the comments, you'd really just do this: IOUtils.copy(System.in, System.out); using the Apache Commons library. That's the most apples-to-apples comparison to more "scripty" languages that have more stuff built in. With Java you pick the libraries/frameworks you want to use. Commons and Guava are extremely popular and robust libraries and really should be included in any comparison against "real world"…

That's right, but it seems like it's fashionable to bash Java inventing example code that noone uses in prodcution. If I would see the code like this, I would ask the one that has written it to justify why he didn't just use IOUtils.copyStream method. Is there some performance reason he wanted to specify buffer size manually? Maybe he wanted to handle exceptions properly instead of wiling silently? Or he was on extre…

It's not just Java that is bashed with this tactic. For example, the TechEmpower benchmarks that keep getting reposted here do the same thing, except with languages other than Java, in order to make Java come out looking better.

Re: Copying stdin to stdout in Java

#49
post #6

Earlier quoted context omitted.

Who never wrote it but assumed we know that the same program in Perl, without using command line switches is while ( ) { print; } Still Awk is shorter: { print } And if you are allowed change the switches of the command line to Perl for your program that Perl program can have exactly 0 bytes .

grep is even shorter: grep $ That reads lines from stdin and echoes to stdout.

Grep expressions are not a turing-complete language, so I guess that won't count. You could claim that you solved the task using a shell script (that invoked the grep "function") but if you programmed in shell, the shortest solution AFAICS is

  #!/bin/sh
  cat

Re: Copying stdin to stdout in Java

#50

Earlier quoted context omitted.

> there is nothing better to do instead of waiting for input. In case no more input is available it would be best to already output the data that have accumulated in buffer. Else in case the input program deadlocks you're never going to see the last (up to 8191) bytes output. This is what non-blocking I/O is for. With non-blocking I/O you first wait until your input channel becomes readable, then reading functions re…

You are right but I was talking about the case when no input was there to be read since the call to `read` and also about this specific application: > Blocking when there is no input is completely ok in this use case as there is nothing better to do instead of waiting for input. (Emphasis is new.)

You're right, I overlooked the reference to the function reading a single byte.
Post reply on HN