-
-
Save kosta/9777932 to your computer and use it in GitHub Desktop.
import java.io.IOException; | |
/** | |
* Class that copies stdin to stdout, as compained about as not being cleanly | |
* writable in Java on Hacker News. | |
* In real code, you would just write IOUtils.copy(System.in, System.out), | |
* which does basically the same thing. | |
* This does not catch any exceptions as a) this is just an "exercise" and | |
* b) all we could do with them is pretty-print them. So let the runtime | |
* print them for you. | |
* | |
* Usage: javac inout.java && echo -e "foo\nbar" | java InOut | |
*/ | |
class InOut { | |
public static void main(String[] args) throws IOException { | |
byte[] buffer = new byte[8192]; | |
while(true) { | |
int bytesRead = System.in.read(buffer); | |
if (bytesRead == -1) { | |
return; | |
} | |
System.out.write(buffer, 0, bytesRead); | |
} | |
} | |
} |
print(input())
That was in python.
But why would you try to "defend" java from some random comment on the net?
Slightly more verbose but yeah, Java clearly wins on clarity :D
!/usr/bin/env python
from sys import stdin
print stdin.read()
Even shorter:
public class Cat {
public static void main(String[] args) throws java.io.IOException {
int i;
do {
System.out.write(i = System.in.read());
} while (i != -1);
}
}
And btw, from my reading of the OpenJDK source, System.in and System.out are already buffered:
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
with buffering:
public static void cat() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
for (;;) {
String line = in.readLine();
if (line == null) break;
System.out.println(line);
}
} catch (IOException ioe) {}
}
Node.js
process.stdin.pipe(process.stdout)
Any terminal that even pretends to act anything like unix:
$ cat
perl -pe1
Using Google's Guava:
ByteStreams.copy(System.in, System.out);
Seem to have some character encoding issues:
C:\p\c\java> cat test4.txt
latin 1
åke är örjan
C:\p\c\java> cat test4.txt | java InOut
latin 1
Õke õr ÷rjan
C:\p\c\java> cat test5.txt
utf 8
åke är örjan
C:\p\c\java> cat test5.txt | java InOut
utf 8
├Ñke ├ñr ├Ârjan
Yeah I know it wasn't part of the "spec" but most the "competing" solutions in other languages handles it for you transparently by using strings instead of bytes.
Seems more like a Windows issue. Works fine on linux (admittedly latin1 doesn't display as it's a utf8 terminal). Converting to characters would be huge overhead on utf8 systems where it would convert utf8 to utf16 and back.
cameron@arch-laptop [09:27:44] [~/tmp]
-> % cat utf8.txt
åke är örjan
cameron@arch-laptop [09:27:47] [~/tmp]
-> % cat latin1.txt
�ke �r �rjan
cameron@arch-laptop [09:27:50] [~/tmp]
-> % cat utf8.txt | java InOut
åke är örjan
cameron@arch-laptop [09:27:56] [~/tmp]
-> % cat latin1.txt | java InOut
�ke �r �rjan
@be5invis It's not that simple. Java isn't converting anything as it's reading it in bytes. I suspect his utf8 file is actually utf16 hence the multibyte characters but either way I think the terminal or cat is doing some funky conversions detecting its going to a terminal not another process which are lost when piped through java. That's the only his terminal can display both unicode and latin1 at the same time.
In Ruby:
puts(gets())
In C#
Console.OpenStandardInput().CopyTo(Console.OpenStandardOutput());
In Racket:
(display (read (current-input-port)))
#!/usr/bin/env ruby
IO.copy_stream(STDIN, STDOUT)
C#
using System;
public class Program
{
public static void Main()
{
while(true)
{
int input = Console.In.Read();
if(input == -1) break;
Console.Out.Write((char)input);
}
}
}
@ssijak I think you misunderstood what that Java program does. It copies the input verbatim to the output.
$ printf 'hello\nworld\n' | python3 -c 'print(input())'
hello
$
It also mangles binary data since it uses print() which will add a newline to the end of its arguments by default (try end=''
to never write a final newline).
$ printf 'binarydata' | python3 -c 'print(input())' | hexdump -C
00000000 62 69 6e 61 72 79 64 61 74 61 0a |binarydata.|
0000000b
instead of...
$ printf 'binarydata' | hexdump -C
00000000 62 69 6e 61 72 79 64 61 74 61 |binarydata|
0000000a
$
Observe there is no newline in the last example.
@17twenty I don't think your program respects binary data either because the print statement needs a final comma to suppress the final newline.
@rShetty Your example appears to only copy the first line in Ruby. Does puts
add a final newline as well?
Anything that "gets a line" uses a newline as a sentinel value and is not a solution. The sentinel of an input stream is an EOF marker (in python the sentinel is an empty string returned from the .read()
method). I think Programming Pearls has a section about the importance of an unique sentinel value.
Python
Using partial
as suggested in Transforming Code into Beautiful Idiomatic Python (the example slide):
from functools import partial
from sys import stdout, stdin
for block in iter(partial(stdin.read, 32), ''):
stdout.write(block)
Note that partial
is optional — lambda: stdin.read(32)
also works.
/In C/
include <stdio.h>
int main(int argc, char **argv)
{
int c;
while((c = getchar()) != EOF)
putchar(c);
return 0;
}
in bash:
echo
In French:
Copiez entrée à la sortie
In Go:
io.Copy(os.Stdout, os.Stdin)
Libraryless:
b := make([]byte, 1024)
for n, err := os.Stdin.Read(b); err == nil; n, err = os.Stdin.Read(b) {
os.Stdout.Write(b[:n])
}
In Turkish:
Girdiyi çıktıya aktar.
uhh I dont understand why this isnt a valid solution
import java.util.Scanner;
public class Main
{
public static void main (String[]args)
{
while(true)
{
Scanner sc = new Scanner(System.in);
System.out.println(sc.nextLine());
}
}
}
as complained about :)