Re: Slightly OT: non-buffered stdin in Java
- In reply to: Aryeh Friedman : "Re: Slightly OT: non-buffered stdin in Java"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 10 Jun 2023 05:38:52 UTC
On 6/8/23 8:35 PM, Aryeh Friedman wrote: > On Thu, Jun 8, 2023 at 11:23 PM Paul Procacci <pprocacci@gmail.com> wrote: >> >> >> On Thu, Jun 8, 2023 at 10:55 PM Aryeh Friedman <aryeh.friedman@gmail.com> wrote: >>> On Thu, Jun 8, 2023 at 10:32 PM Paul Procacci <pprocacci@gmail.com> wrote: >>>> >>>> >>>> On Thu, Jun 8, 2023 at 9:22 PM Aryeh Friedman <aryeh.friedman@gmail.com> wrote: >>>>> On Thu, Jun 8, 2023 at 6:37 PM Dr. Nikolaus Klepp <dr.klepp@gmx.at> wrote: >>>>>> Anno domini 2023 Thu, 8 Jun 17:22:38 -0400 >>>>>> Aryeh Friedman scripsit: >>>>>>> On Thu, Jun 8, 2023 at 2:39 PM Dr. Nikolaus Klepp <dr.klepp@gmx.at> wrote: >>>>>>>> Anno domini 2023 Thu, 8 Jun 14:01:19 -0400 >>>>>>>> Aryeh Friedman scripsit: >>>>>>>>> Under Java stdin (System.in) is a buffered stream not sent to the >>>>>>>>> application until return is pressed. But, Java can read from >>>>>>>>> files/sockets and other generic InputStreams unbuffered. So I was >>>>>>>>> wondering if there is a command that will make stdin go to a file so >>>>>>>>> that Java can open that file and read it unbuffered? >>>>>>>>> >>>>>>>>> I know I can do something like cat ->file but that makes it hard to >>>>>>>>> sync stdout and stderr (both are unbuffered in Java) with the file >>>>>>>>> version of stdin >>>>>>>>> >>>>>>>> "stdbuf" might be what you look for: >>>>>>>> >>>>>>>> https://man.freebsd.org/cgi/man.cgi?query=stdbuf >>>>>>> Will likely need to play with it more but stdbuf -i 0 -o 0 cat -|cat >>>>>>> didn't produce the expected immediate echo I still had to hit return >>>>>>> >>>>>> Your console is linebuffered, so "cat" receives lines. IIRC "cat" disables linebuffer on input by itself, so you should use someting else for testing. >>>>>> >>>>>> Nik >>>>>> >>>>> I am pretty convinced by the following test it is not working as advertised: >>>>> >>>>> aryehl@neomarx:~/Desktop % cat foo.c >>>>> #include <stdio.h> >>>>> #include <fcntl.h> >>>>> #include <unistd.h> >>>>> >>>>> int main() >>>>> { >>>>> int in=fcntl(STDIN_FILENO, F_DUPFD, 0); >>>>> int out=fcntl(STDOUT_FILENO, F_DUPFD, 0); >>>>> char c=0; >>>>> >>>>> do { >>>>> read(in,&c,1); >>>>> write(out,&c,1); >>>>> } while(c!=EOF); >>>>> } >>>>> aryehl@neomarx:~/Desktop % !cc >>>>> cc foo.c >>>>> aryehl@neomarx:~/Desktop % stdbuf -i 0 -o 0 ./a.out >>>>> this is not echoing! >>>>> this is not echoing! >>>>> neither is this >>>>> neither is this >>>>> ^C >>>>> aryehl@neomarx:~/Desktop % >>>>> >>>>> -- >>>>> Aryeh M. Friedman, Lead Developer, http://www.PetiteCloud.org >>>>> >>>> stdbuf only works for stdio buffering of which read(2) and write(2) aren't. >>> I also tried it with System.in.read() in Java and it was also buffered >>> but according to the openjdk source it appears that this is on >>> purpose. >>> >>> >>> >>> -- >>> Aryeh M. Friedman, Lead Developer, http://www.PetiteCloud.org >> >> >> When you just `./a.out` you're being bitten by the tty. >> You can manipulate that terminal to do what you want. Start reading termios(4). >> >> Without a tty you will only get a character at a time with the following: >> >> #include <unistd.h> >> >> int main(int argc, char **argv) >> { >> char ch; >> for(;;){ >> ssize_t r = read(0,&ch,1); >> if(!r) break; >> write(1, &ch, 1); >> } >> _exit(0); >> } > Please see the whole context the goal is to make it so I can type at > the command line into a java program and have instantaneous > presentation of any characters I enter to Java > If you want to type at the command line while running a Java program and have it be able to see each character at a time then maybe what you want is java.io.Console https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Console.html You can then get a Reader from the console and call read() on that to read a single character. -- Greg