IO Cancellation while reading from console

S

Sadalsud

I'm writing a console application where the user has to enter some text at a
prompt within a set time period. If the user has not entered anything within
that time period, I need to interrupt that operation and move on to someting
else. I've tried doing it with the sample code below. I figured that closing
the input stream would cause an IOException to be raised for the current
read(), but that does not seem to be happening. If anyone has any suggestions,
it would be greatly appreciated. I'm using Java 1.4.2 on a Debian Linux system.

/*start sample code*/
/*I would like the first readLine() to be interrupted after 5 seconds, but it
is never interrupted. As expected though, I do get an exception on the 2nd
readLine(), but that doesn't do me much good*/
import java.util.*;
import java.io.*;

public class CancelingInput {
Timer t;
InputStreamReader inputStream;
BufferedReader reader;
String response;

public static void main(String args[]) throws Exception {
CancelingInput c = new CancelingInput();
}

public CancelingInput() throws Exception {
inputStream = new InputStreamReader(System.in);
reader = new BufferedReader(inputStream);

t = new Timer(true);
t.schedule(new ClosingTask(), 5*1000);

System.out.print("Wait 6 seconds to enter (I would like for this to be
interrupted after 5 seconds) text: ");
response = reader.readLine();
System.out.println("Input: " + response);

System.out.print("Now enter one last line of text: ");
response = reader.readLine();
System.out.println("Input: " + response);
}

class ClosingTask extends TimerTask {
public ClosingTask() {}
public void run() {
try {
inputStream.close();
reader.close();
}
catch(IOException e) {
System.out.println("Error closing streams");
}
}
}
}
 
F

Filip Larsen

I'm writing a console application where the user has to enter some text at a
prompt within a set time period. If the user has not entered anything within
that time period, I need to interrupt that operation and move on to someting
else. I've tried doing it with the sample code below. I figured that closing
the input stream would cause an IOException to be raised for the current
read(), but that does not seem to be happening. If anyone has any suggestions,
it would be greatly appreciated. I'm using Java 1.4.2 on a Debian
Linux system.

The problem is that the thread that makes a read from System.in will
block in a way that cannot be interrupted. So one way to read a line
with timeout is then to put the actual reader in its own thread, like
illustrated with the BackgroundConsoleReader class below.

Another way to do it might be to use the new I/O (package java.nio)
which supports interruptible channels. However, I haven't researced how
to read from System.in using nio, so I cannot help you there.


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BackgroundConsoleReader extends Thread {

public static void main(String[] args) {
BackgroundConsoleReader rt = new BackgroundConsoleReader();
rt.start();
String line = "";
while (line != null) {
System.out.print("Enter line:");
line = rt.readLine(5000L);
if (line != null) {
System.out.println("read : " + line);
}
}
System.out.println();
System.out.println("done");
}

public BackgroundConsoleReader() {
this.in = new BufferedReader(new InputStreamReader(System.in));
this.setDaemon(true);
}

public void run() {
try {
while (true) {
String s = in.readLine();
synchronized (this) {
line = s;
notifyAll();
}
}
} catch (IOException e) {
}
}

public synchronized String readLine(long timeout) {
line = null;
try {
wait(timeout);
} catch (InterruptedException e) {
}
return line;
}

private BufferedReader in;
private String line;

}


Regards,
 
S

Sadalsud

Filip Larsen" [email protected] said:
The problem is that the thread that makes a read from System.in will
block in a way that cannot be interrupted. So one way to read a line
with timeout is then to put the actual reader in its own thread, like
illustrated with the BackgroundConsoleReader class below.

Another way to do it might be to use the new I/O (package java.nio)
which supports interruptible channels. However, I haven't researced how
to read from System.in using nio, so I cannot help you there.

*snip code*

I briefly looked over the java.nio.channels package, but I didn't see anything
that would help me out to much. Thank you for the code sample, I should be able
to adapt it for my program.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top