How to make (Java) program end automatically if input from PIPE is over using InputStream



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















This question could be better rephrased as: How do you detect EOF in InputStream without blocking



I have a java program that is able to take input from System.in directly (without using a Scanner), I can also pipe input into the java program directly just like any program. However, when I pipe input into the program, the program keeps running. The idea is to stop the program if input was piped into it, but keep it running if we are waiting for user input.



My question is how do I use an InputStream to detect when the pipe is over (and end the program)? If I was using a Scanner I understand that I would be able to use Scanner#hasNext() to detect if I can read more however, I would like to do this just with an InputStream if possible.



My code currently looks something similar to this:



final InputStream in = System.in; // sometimes in won't be System.in
final byte buffer = new byte[1024];
while(true)
int len;
// the reason I use in.available() is so I only read if in.read() won't block
while(in.available() > 0 && (len = in.read(buffer)) > -1)
String s = new String(buffer, 0, len);
// do something with string

// sometimes do other stuff not relevant to this question



I am open to simpler solutions. The reason I am not using a Scanner object is because I need to read individual chars at a time, not just lines at a time. The purpose of this program isn't only input from the user, most of the time the input isn't even from System.in, I just included System.in in the above example because it will sometimes be System.in



EDIT:
For whatever reason, I've dedicated about 2 hours of my life searching the internet for a simple solution for this. I've tried just using an InputStream, and even converted my code to use a ReadableByteChannel (created using Channels.newChannel()) to see if that would work. Every implementation I could find for something that wraps an InputStream is blocking. I guess the only way to fix this is to use another thread. Good luck future viewers.










share|improve this question






























    1















    This question could be better rephrased as: How do you detect EOF in InputStream without blocking



    I have a java program that is able to take input from System.in directly (without using a Scanner), I can also pipe input into the java program directly just like any program. However, when I pipe input into the program, the program keeps running. The idea is to stop the program if input was piped into it, but keep it running if we are waiting for user input.



    My question is how do I use an InputStream to detect when the pipe is over (and end the program)? If I was using a Scanner I understand that I would be able to use Scanner#hasNext() to detect if I can read more however, I would like to do this just with an InputStream if possible.



    My code currently looks something similar to this:



    final InputStream in = System.in; // sometimes in won't be System.in
    final byte buffer = new byte[1024];
    while(true)
    int len;
    // the reason I use in.available() is so I only read if in.read() won't block
    while(in.available() > 0 && (len = in.read(buffer)) > -1)
    String s = new String(buffer, 0, len);
    // do something with string

    // sometimes do other stuff not relevant to this question



    I am open to simpler solutions. The reason I am not using a Scanner object is because I need to read individual chars at a time, not just lines at a time. The purpose of this program isn't only input from the user, most of the time the input isn't even from System.in, I just included System.in in the above example because it will sometimes be System.in



    EDIT:
    For whatever reason, I've dedicated about 2 hours of my life searching the internet for a simple solution for this. I've tried just using an InputStream, and even converted my code to use a ReadableByteChannel (created using Channels.newChannel()) to see if that would work. Every implementation I could find for something that wraps an InputStream is blocking. I guess the only way to fix this is to use another thread. Good luck future viewers.










    share|improve this question


























      1












      1








      1








      This question could be better rephrased as: How do you detect EOF in InputStream without blocking



      I have a java program that is able to take input from System.in directly (without using a Scanner), I can also pipe input into the java program directly just like any program. However, when I pipe input into the program, the program keeps running. The idea is to stop the program if input was piped into it, but keep it running if we are waiting for user input.



      My question is how do I use an InputStream to detect when the pipe is over (and end the program)? If I was using a Scanner I understand that I would be able to use Scanner#hasNext() to detect if I can read more however, I would like to do this just with an InputStream if possible.



      My code currently looks something similar to this:



      final InputStream in = System.in; // sometimes in won't be System.in
      final byte buffer = new byte[1024];
      while(true)
      int len;
      // the reason I use in.available() is so I only read if in.read() won't block
      while(in.available() > 0 && (len = in.read(buffer)) > -1)
      String s = new String(buffer, 0, len);
      // do something with string

      // sometimes do other stuff not relevant to this question



      I am open to simpler solutions. The reason I am not using a Scanner object is because I need to read individual chars at a time, not just lines at a time. The purpose of this program isn't only input from the user, most of the time the input isn't even from System.in, I just included System.in in the above example because it will sometimes be System.in



      EDIT:
      For whatever reason, I've dedicated about 2 hours of my life searching the internet for a simple solution for this. I've tried just using an InputStream, and even converted my code to use a ReadableByteChannel (created using Channels.newChannel()) to see if that would work. Every implementation I could find for something that wraps an InputStream is blocking. I guess the only way to fix this is to use another thread. Good luck future viewers.










      share|improve this question
















      This question could be better rephrased as: How do you detect EOF in InputStream without blocking



      I have a java program that is able to take input from System.in directly (without using a Scanner), I can also pipe input into the java program directly just like any program. However, when I pipe input into the program, the program keeps running. The idea is to stop the program if input was piped into it, but keep it running if we are waiting for user input.



      My question is how do I use an InputStream to detect when the pipe is over (and end the program)? If I was using a Scanner I understand that I would be able to use Scanner#hasNext() to detect if I can read more however, I would like to do this just with an InputStream if possible.



      My code currently looks something similar to this:



      final InputStream in = System.in; // sometimes in won't be System.in
      final byte buffer = new byte[1024];
      while(true)
      int len;
      // the reason I use in.available() is so I only read if in.read() won't block
      while(in.available() > 0 && (len = in.read(buffer)) > -1)
      String s = new String(buffer, 0, len);
      // do something with string

      // sometimes do other stuff not relevant to this question



      I am open to simpler solutions. The reason I am not using a Scanner object is because I need to read individual chars at a time, not just lines at a time. The purpose of this program isn't only input from the user, most of the time the input isn't even from System.in, I just included System.in in the above example because it will sometimes be System.in



      EDIT:
      For whatever reason, I've dedicated about 2 hours of my life searching the internet for a simple solution for this. I've tried just using an InputStream, and even converted my code to use a ReadableByteChannel (created using Channels.newChannel()) to see if that would work. Every implementation I could find for something that wraps an InputStream is blocking. I guess the only way to fix this is to use another thread. Good luck future viewers.







      java input pipe inputstream blocking






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 3:23







      retodaredevil

















      asked Nov 14 '18 at 1:25









      retodaredevilretodaredevil

      38149




      38149






















          3 Answers
          3






          active

          oldest

          votes


















          0














          You don't really need in.available().
          When the pipe is depleted, your variable len will be -1 and the internal while loop will end. You can just break the external while loop depending on your need.






          share|improve this answer























          • My problem is that I cannot call read whenever I want because that will sometimes block, that's why I only read if in.available() > 0 which doesn't tell me if the pipe is depleted.

            – retodaredevil
            Nov 14 '18 at 1:35











          • In that case, you might want to consider using a separate thread to read or use NIO2

            – tanyehzheng
            Nov 14 '18 at 1:36












          • ah, another Thread is what I was afraid of. I'll look at nio.2 and see what the best option is. Thanks

            – retodaredevil
            Nov 14 '18 at 1:40


















          0














          Sitting in a while loop and calling in.available is not efficient. It will use a lot of CPU.



          If you call in.read() and it returns -1 then it means there is no more input to read. So you should do this but of course then it blocks.



          If you need to do something else while this is going on then use a different Thread for the other code. Make sure to set that other thread as a daemon thread so it does not keep the program running when this main thread's method finishes.






          share|improve this answer






























            0














            Simply remember whether read() returned -1, i.e. increase the scope of len.



            final InputStream in = System.in;
            final byte buffer = new byte[1024];
            for (int len = 0; len != -1; )
            while (in.available() > 0 && (len = in.read(buffer)) != -1)
            String s = new String(buffer, 0, len);
            // do something with string

            // do other stuff






            share|improve this answer


















            • 1





              Ah I really wished that worked. I found that when calling in.read(), it would give me all the bytes until the end of the file, returning a positive length, and then the next call to in.available() == 0 which would stop me from calling in.read() again when it would return -1 (if I had called it)

              – retodaredevil
              Nov 14 '18 at 2:08











            • @retodaredevil Which means that it cannot be done like this, and you have to use threads like other answers have suggested.

              – Andreas
              Nov 14 '18 at 2:19











            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291868%2fhow-to-make-java-program-end-automatically-if-input-from-pipe-is-over-using-in%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            You don't really need in.available().
            When the pipe is depleted, your variable len will be -1 and the internal while loop will end. You can just break the external while loop depending on your need.






            share|improve this answer























            • My problem is that I cannot call read whenever I want because that will sometimes block, that's why I only read if in.available() > 0 which doesn't tell me if the pipe is depleted.

              – retodaredevil
              Nov 14 '18 at 1:35











            • In that case, you might want to consider using a separate thread to read or use NIO2

              – tanyehzheng
              Nov 14 '18 at 1:36












            • ah, another Thread is what I was afraid of. I'll look at nio.2 and see what the best option is. Thanks

              – retodaredevil
              Nov 14 '18 at 1:40















            0














            You don't really need in.available().
            When the pipe is depleted, your variable len will be -1 and the internal while loop will end. You can just break the external while loop depending on your need.






            share|improve this answer























            • My problem is that I cannot call read whenever I want because that will sometimes block, that's why I only read if in.available() > 0 which doesn't tell me if the pipe is depleted.

              – retodaredevil
              Nov 14 '18 at 1:35











            • In that case, you might want to consider using a separate thread to read or use NIO2

              – tanyehzheng
              Nov 14 '18 at 1:36












            • ah, another Thread is what I was afraid of. I'll look at nio.2 and see what the best option is. Thanks

              – retodaredevil
              Nov 14 '18 at 1:40













            0












            0








            0







            You don't really need in.available().
            When the pipe is depleted, your variable len will be -1 and the internal while loop will end. You can just break the external while loop depending on your need.






            share|improve this answer













            You don't really need in.available().
            When the pipe is depleted, your variable len will be -1 and the internal while loop will end. You can just break the external while loop depending on your need.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 14 '18 at 1:31









            tanyehzhengtanyehzheng

            1,70311633




            1,70311633












            • My problem is that I cannot call read whenever I want because that will sometimes block, that's why I only read if in.available() > 0 which doesn't tell me if the pipe is depleted.

              – retodaredevil
              Nov 14 '18 at 1:35











            • In that case, you might want to consider using a separate thread to read or use NIO2

              – tanyehzheng
              Nov 14 '18 at 1:36












            • ah, another Thread is what I was afraid of. I'll look at nio.2 and see what the best option is. Thanks

              – retodaredevil
              Nov 14 '18 at 1:40

















            • My problem is that I cannot call read whenever I want because that will sometimes block, that's why I only read if in.available() > 0 which doesn't tell me if the pipe is depleted.

              – retodaredevil
              Nov 14 '18 at 1:35











            • In that case, you might want to consider using a separate thread to read or use NIO2

              – tanyehzheng
              Nov 14 '18 at 1:36












            • ah, another Thread is what I was afraid of. I'll look at nio.2 and see what the best option is. Thanks

              – retodaredevil
              Nov 14 '18 at 1:40
















            My problem is that I cannot call read whenever I want because that will sometimes block, that's why I only read if in.available() > 0 which doesn't tell me if the pipe is depleted.

            – retodaredevil
            Nov 14 '18 at 1:35





            My problem is that I cannot call read whenever I want because that will sometimes block, that's why I only read if in.available() > 0 which doesn't tell me if the pipe is depleted.

            – retodaredevil
            Nov 14 '18 at 1:35













            In that case, you might want to consider using a separate thread to read or use NIO2

            – tanyehzheng
            Nov 14 '18 at 1:36






            In that case, you might want to consider using a separate thread to read or use NIO2

            – tanyehzheng
            Nov 14 '18 at 1:36














            ah, another Thread is what I was afraid of. I'll look at nio.2 and see what the best option is. Thanks

            – retodaredevil
            Nov 14 '18 at 1:40





            ah, another Thread is what I was afraid of. I'll look at nio.2 and see what the best option is. Thanks

            – retodaredevil
            Nov 14 '18 at 1:40













            0














            Sitting in a while loop and calling in.available is not efficient. It will use a lot of CPU.



            If you call in.read() and it returns -1 then it means there is no more input to read. So you should do this but of course then it blocks.



            If you need to do something else while this is going on then use a different Thread for the other code. Make sure to set that other thread as a daemon thread so it does not keep the program running when this main thread's method finishes.






            share|improve this answer



























              0














              Sitting in a while loop and calling in.available is not efficient. It will use a lot of CPU.



              If you call in.read() and it returns -1 then it means there is no more input to read. So you should do this but of course then it blocks.



              If you need to do something else while this is going on then use a different Thread for the other code. Make sure to set that other thread as a daemon thread so it does not keep the program running when this main thread's method finishes.






              share|improve this answer

























                0












                0








                0







                Sitting in a while loop and calling in.available is not efficient. It will use a lot of CPU.



                If you call in.read() and it returns -1 then it means there is no more input to read. So you should do this but of course then it blocks.



                If you need to do something else while this is going on then use a different Thread for the other code. Make sure to set that other thread as a daemon thread so it does not keep the program running when this main thread's method finishes.






                share|improve this answer













                Sitting in a while loop and calling in.available is not efficient. It will use a lot of CPU.



                If you call in.read() and it returns -1 then it means there is no more input to read. So you should do this but of course then it blocks.



                If you need to do something else while this is going on then use a different Thread for the other code. Make sure to set that other thread as a daemon thread so it does not keep the program running when this main thread's method finishes.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 14 '18 at 1:44









                Sarel BothaSarel Botha

                10.2k74554




                10.2k74554





















                    0














                    Simply remember whether read() returned -1, i.e. increase the scope of len.



                    final InputStream in = System.in;
                    final byte buffer = new byte[1024];
                    for (int len = 0; len != -1; )
                    while (in.available() > 0 && (len = in.read(buffer)) != -1)
                    String s = new String(buffer, 0, len);
                    // do something with string

                    // do other stuff






                    share|improve this answer


















                    • 1





                      Ah I really wished that worked. I found that when calling in.read(), it would give me all the bytes until the end of the file, returning a positive length, and then the next call to in.available() == 0 which would stop me from calling in.read() again when it would return -1 (if I had called it)

                      – retodaredevil
                      Nov 14 '18 at 2:08











                    • @retodaredevil Which means that it cannot be done like this, and you have to use threads like other answers have suggested.

                      – Andreas
                      Nov 14 '18 at 2:19















                    0














                    Simply remember whether read() returned -1, i.e. increase the scope of len.



                    final InputStream in = System.in;
                    final byte buffer = new byte[1024];
                    for (int len = 0; len != -1; )
                    while (in.available() > 0 && (len = in.read(buffer)) != -1)
                    String s = new String(buffer, 0, len);
                    // do something with string

                    // do other stuff






                    share|improve this answer


















                    • 1





                      Ah I really wished that worked. I found that when calling in.read(), it would give me all the bytes until the end of the file, returning a positive length, and then the next call to in.available() == 0 which would stop me from calling in.read() again when it would return -1 (if I had called it)

                      – retodaredevil
                      Nov 14 '18 at 2:08











                    • @retodaredevil Which means that it cannot be done like this, and you have to use threads like other answers have suggested.

                      – Andreas
                      Nov 14 '18 at 2:19













                    0












                    0








                    0







                    Simply remember whether read() returned -1, i.e. increase the scope of len.



                    final InputStream in = System.in;
                    final byte buffer = new byte[1024];
                    for (int len = 0; len != -1; )
                    while (in.available() > 0 && (len = in.read(buffer)) != -1)
                    String s = new String(buffer, 0, len);
                    // do something with string

                    // do other stuff






                    share|improve this answer













                    Simply remember whether read() returned -1, i.e. increase the scope of len.



                    final InputStream in = System.in;
                    final byte buffer = new byte[1024];
                    for (int len = 0; len != -1; )
                    while (in.available() > 0 && (len = in.read(buffer)) != -1)
                    String s = new String(buffer, 0, len);
                    // do something with string

                    // do other stuff







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 14 '18 at 1:45









                    AndreasAndreas

                    79.9k465129




                    79.9k465129







                    • 1





                      Ah I really wished that worked. I found that when calling in.read(), it would give me all the bytes until the end of the file, returning a positive length, and then the next call to in.available() == 0 which would stop me from calling in.read() again when it would return -1 (if I had called it)

                      – retodaredevil
                      Nov 14 '18 at 2:08











                    • @retodaredevil Which means that it cannot be done like this, and you have to use threads like other answers have suggested.

                      – Andreas
                      Nov 14 '18 at 2:19












                    • 1





                      Ah I really wished that worked. I found that when calling in.read(), it would give me all the bytes until the end of the file, returning a positive length, and then the next call to in.available() == 0 which would stop me from calling in.read() again when it would return -1 (if I had called it)

                      – retodaredevil
                      Nov 14 '18 at 2:08











                    • @retodaredevil Which means that it cannot be done like this, and you have to use threads like other answers have suggested.

                      – Andreas
                      Nov 14 '18 at 2:19







                    1




                    1





                    Ah I really wished that worked. I found that when calling in.read(), it would give me all the bytes until the end of the file, returning a positive length, and then the next call to in.available() == 0 which would stop me from calling in.read() again when it would return -1 (if I had called it)

                    – retodaredevil
                    Nov 14 '18 at 2:08





                    Ah I really wished that worked. I found that when calling in.read(), it would give me all the bytes until the end of the file, returning a positive length, and then the next call to in.available() == 0 which would stop me from calling in.read() again when it would return -1 (if I had called it)

                    – retodaredevil
                    Nov 14 '18 at 2:08













                    @retodaredevil Which means that it cannot be done like this, and you have to use threads like other answers have suggested.

                    – Andreas
                    Nov 14 '18 at 2:19





                    @retodaredevil Which means that it cannot be done like this, and you have to use threads like other answers have suggested.

                    – Andreas
                    Nov 14 '18 at 2:19

















                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291868%2fhow-to-make-java-program-end-automatically-if-input-from-pipe-is-over-using-in%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    PHP code is not being executed, instead code shows on the page

                    Administrative divisions of China

                    Cardinality of the set of algorithms