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;
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
add a comment |
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
add a comment |
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
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
java input pipe inputstream blocking
edited Nov 14 '18 at 3:23
retodaredevil
asked Nov 14 '18 at 1:25
retodaredevilretodaredevil
38149
38149
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
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.
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 toreador 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
add a comment |
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.
add a comment |
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
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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 toreador 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
add a comment |
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.
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 toreador 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
add a comment |
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.
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.
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 toreador 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
add a comment |
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 toreador 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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 14 '18 at 1:44
Sarel BothaSarel Botha
10.2k74554
10.2k74554
add a comment |
add a comment |
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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