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