Console input no longer being echo'd after changing stdout - java

In my program I have changed stdout using System.setOut(); but after that, typing into the console no longer echoes the input back.
I tried the following, with no avail:
originalStdIn = System.in;
stdIn = new InputStream() {
#Override
public int available() throws IOException {
return originalStdIn.available();
}
#Override
public int read() throws IOException {
int chr = originalStdIn.read();
stdOut.write(chr);
return chr;
}
#Override
public int read(byte[] buffer) throws IOException {
return this.read(buffer, 0, buffer.length);
}
#Override
public int read(byte[] buffer, int off, int len) throws IOException {
int readResult = originalStdIn.read(buffer, off, len);
stdOut.write(buffer, off, readResult);
return readResult;
}
};
System.setIn(stdIn);
This is how I read input:
private void handleThread_func() {
Logging.didUpdateInWindow = true;
System.out.print(this.consoleInputPrefix);
while (!this.isClosed) {
try {
if (System.in.available() > 0) {
String input = "";
while (System.in.available() > 0) {
input += this.inputReader.readLine();
}
this.handleInput(input);
Logging.didUpdateInWindow = true;
System.out.print(this.consoleInputPrefix);
}
Thread.sleep(1);
} catch (Exception ex) {
if (ex instanceof InterruptedException) break;
Logging.logSevere("Unable to handle console input: " +
Utils.getExceptionStackTraceAsStr(ex));
}
}
}
I tried changing input += this.inputReader.readLine(); to input += (char)this.inputReader.read() but while it did echo, the input was read in the incorrect order

Related

Exception Thrown When Using Scanner in loop?

I'm working on reading integers into a list in Java, and I found an exception that gets thrown when putting Scanner & nextInt() in the loop.
Exception gets thrown on the Scanner class in this code:
do{
System.out.println("?");
Scanner in = new Scanner(System.in);
input = in.nextInt();
in.close();
if(input != SENTINEL)
numberList.add(input);
}while(input != SENTINEL);
Whereas moving the Scanner initialization and close outside of the loop works just fine:
Scanner in = new Scanner(System.in);
//receive input integers from user
do{
System.out.println("?");
input = in.nextInt();
if(input != SENTINEL)
numberList.add(input);
}while(input != SENTINEL);
in.close();
Why is it that the exception occurs when initializing the Scanner class in the loop? Thanks!
Exception is:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at main.Run.main(Run.java:25)
The reason that the first version crashes is that calling to Scanner.close - also closes the underlying stream: System.in.
It can be proved by wrapping System.in with a class that doesn't do anything in close() method (the code for UnClosableDecorator was taken from here):
public class Play {
public static void main(String[] arg) throws IOException {
int SENTINEL = 10;
int input = 0;
List<Integer> numberList = new ArrayList<>();
System.setIn(new UnClosableDecorator(System.in));
do {
Scanner in = new Scanner(System.in);
System.out.println("?");
input = in.nextInt();
System.out.println("[" + input + "]");
in.close();
if(input != SENTINEL) {
numberList.add(input);
}
} while(input != SENTINEL);
System.out.println("done");
}
}
class UnClosableDecorator extends InputStream {
private final InputStream inputStream;
public UnClosableDecorator(InputStream inputStream) {
this.inputStream = inputStream;
}
#Override
public int read() throws IOException {
return inputStream.read();
}
#Override
public int read(byte[] b) throws IOException {
return inputStream.read(b);
}
#Override
public int read(byte[] b, int off, int len) throws IOException {
return inputStream.read(b, off, len);
}
#Override
public long skip(long n) throws IOException {
return inputStream.skip(n);
}
#Override
public int available() throws IOException {
return inputStream.available();
}
#Override
public synchronized void mark(int readlimit) {
inputStream.mark(readlimit);
}
#Override
public synchronized void reset() throws IOException {
inputStream.reset();
}
#Override
public boolean markSupported() {
return inputStream.markSupported();
}
#Override
public void close() throws IOException {
//do nothing
}
}

Run JTape Library on Java (java library path)

I am trying to use the JTape Library to read some data from a DDS4 magnetic tape.
I want to use eclipse to run my code under Linux 12.04 LTS
The problem is that I cannot let eclipse reference the TapeLinux.c Library in any way.
PROBLEM:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no TapeLinux in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1088)
at BasicTapeDevice.<clinit>(BasicTapeDevice.java:169)
at TestEOD.main(TestEOD.java:12)
This are my classes:
/* TestEOD.java */
import java.io.*;
public class TestEOD {
public static void main(String[] args) throws IOException {
/* if (args.length != 1) {
System.err.println("Usage: java TestEOD <path to device>");
System.exit(1);
}*/
BasicTapeDevice d = new BasicTapeDevice("/dev/nst0");
System.out.print("Rewinding...");
System.out.flush();
d.rewind();
System.out.println("done!");
System.out.print("Spacing to end of data...");
System.out.flush();
d.spaceEOD();
System.out.println("done!");
}
}
/* BasicTapeDevice.java */
import java.io.*;
public class BasicTapeDevice {
private FileDescriptor fd;
private InputStream in;
private OutputStream out;
private boolean eof;
private boolean eom;
private boolean ignoreEOM;
public BasicTapeDevice(String pathName) throws IOException {
fd = new FileDescriptor();
tapeOpen(pathName);
in = new TapeInputStream();
out = new TapeOutputStream();
eof = false;
eom = false;
ignoreEOM = false;
}
public synchronized void close() throws IOException {
if (fd != null) {
try {
if (fd.valid()) {
tapeClose();
}
} finally {
fd = null;
}
}
}
public InputStream getInputStream() throws IOException {
ensureOpen();
return in;
}
public OutputStream getOutputStream() throws IOException {
ensureOpen();
return out;
}
public int getBlockSize() throws IOException {
ensureOpen();
return tapeGetBlockSize();
}
public void setBlockSize(int bs) throws IOException {
ensureOpen();
tapeSetBlockSize(bs);
}
public void rewind() throws IOException {
ensureOpen();
tapeRewind();
}
public void spaceEOD() throws IOException {
ensureOpen();
tapeSpaceEOD();
}
public void clearEOF() throws IOException {
ensureOpen();
if (eof) {
eof = false;
/* assume that the file mark has already been skipped */
} else {
throw new IOException("not at end of file");
}
}
public void clearEOM() throws IOException {
ensureOpen();
if (eom) {
ignoreEOM = true;
} else {
throw new IOException("not at logical end of media");
}
}
class TapeInputStream extends InputStream {
private byte[] temp = new byte[1];
public int read() throws IOException {
int n = read(temp, 0, 1);
if (n <= 0) {
return -1;
}
return temp[0] & 0xff;
}
public int read(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
}
if (off < 0 || len < 0 || off+len > b.length) {
throw new IndexOutOfBoundsException();
}
if (len == 0) {
return 0;
}
if (eof) {
return -1;
}
ensureOpen();
int n = tapeRead(b, off, len);
if (n <= 0) {
return -1;
}
return n;
}
public long skip(long numbytes) throws IOException {
return 0;
}
public void close() throws IOException {
BasicTapeDevice.this.close();
}
}
class TapeOutputStream extends OutputStream {
private byte[] temp = new byte[1];
public void write(int b) throws IOException {
temp[0] = (byte) b;
write(temp, 0, 1);
}
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
public void write(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
}
if (off < 0 || len < 0 || off+len > b.length) {
throw new IndexOutOfBoundsException();
}
if (eom && !ignoreEOM) {
throw new LogicalEOMException("logical end-of-media");
}
int n = tapeWrite(b, off, len);
while (n < len) {
n += tapeWrite(b, off + n, len - n);
}
}
public void close() throws IOException {
BasicTapeDevice.this.close();
}
}
protected void finalize() {
try {
close();
} catch (IOException ex) {
}
}
private void ensureOpen() throws IOException {
if (fd == null || !fd.valid()) {
throw new IOException("tape device is not open");
}
}
private static native void initFields();
private native void tapeOpen(String pathName) throws IOException;
private native void tapeClose() throws IOException;
private native int tapeRead(byte[] b, int off, int len) throws IOException;
private native int tapeWrite(byte[] b, int off, int len) throws IOException;
private native int tapeGetBlockSize() throws IOException;
private native void tapeSetBlockSize(int bs) throws IOException;
private native void tapeRewind() throws IOException;
private native void tapeSpaceEOD() throws IOException;
/* load the JNI library specific for this platform */
static {
StringBuffer buf = new StringBuffer("Tape");
String osName = System.getProperty("os.name");
if (osName.equals("Windows NT") || osName.equals("Windows 2000")) {
buf.append("WinNT");
} else {
buf.append(osName);
}
System.loadLibrary(buf.toString());
initFields();
}
}
WHAT I HAVE TRIED
I have looked around that what I need is to include the path of the folder which contains the file TapeLinux.c
I have tried all these answers and nothing change
Can you please help me to figure out how I can use JNI in this situation and what I should configure to run my code
Thanks
Since you are on Linux, the message ...main java.lang.UnsatisfiedLinkError: no TapeLinux in java... likely means the library named libTapeLinux.so could not be found.
Seems you are searching for a solution by trying to locate TapeLinux.c and you should be searching for libTapeLinux.so and once you find it make sure libTapeLinux.so is on the load path.

What is the best way to convert an Input Stream to an Array in Java?

I'm writing code that will accept byte values from an arduino, store them as an array, preform some mathematical calculations, and then send the values back to the arduino. Right now I can send 127 values to the Arduino and I get 127 values back, but they are of type string, and any attempts to use the Integer class to convert these strings results in a program hang. I believe the buffer sometimes provides empty strings, and parseInt() doesn't know what to do. Does anyone have any suggestions? I'm very much a beginner in java and would be open to better solutions.
Here is my code:
package GridMap;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
*
*/
public class SerialWriter implements Runnable {
OutputStream out;
byte array[] = new byte[10];
byte c;
public SerialWriter(OutputStream out, byte[] in) {
this.out = out;
array = in;
}
public void run() {
try {
int index = 0;
c = array[index];
while ((c) > -1) {
this.out.write(c);
System.out.println("sent " + c);
if (index == 64){
Thread.sleep(2);
}
index++;
c = array[index];
}
TwoWaySerialComm.recieve();
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
}
public class SerialReader implements Runnable {
static byte[] output = new byte[128];
private InputStream in;
private int[] buffer = new int[11];
static SerialPort thisSerialPort;
static OutputStream thisOut;
static String total = new String("333");
public SerialReader(InputStream in) {
this.in = in;
for (byte i = 0; i < 127; i++) {
output[i] = i;
}
output[127] = - 1;
}
public void run ()
{
byte[] buffer = new byte[1024];
int len = -1;
int index = 0;
int value;
try
{
Thread.sleep(200);
while (( len = this.in.read(buffer)) > -1 && index < 200)
{
String string = new String(buffer, 0, len);
//value = Integer.getInteger(string, len);
// System.out.print(value);
//System.out.println("buffer" + value);
System.out.print(string);
index++;
}
TwoWaySerialComm.send(output);
}
catch (Exception e )
{
e.printStackTrace();
}
}
public static int byteArrayToInt(byte[] b)
{
return b[3] & 0xFF |
(b[2] & 0xFF) << 8 |
(b[1] & 0xFF) << 16 |
(b[0] & 0xFF) << 24;
}
}
public class TwoWaySerialComm {
static SerialPort serialPort;
static OutputStream out = null;
static InputStream in;
static Thread receiveThread;
static Thread sendThread;
static byte[] output = new byte[11];
public TwoWaySerialComm() {
super();
}
void connect(String portName) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Error: Port is currently in use");
} else {
CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
if (commPort instanceof SerialPort) {
serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(114400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} else {
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}
static void send(byte[] output) {
try {
out = serialPort.getOutputStream();
sendThread = new Thread(new SerialWriter(out, output));
sendThread.start();
//sendThread.join();
} catch (Exception e) {
System.out.println("Port Not Avaialable (send) ");
}
}
static void recieve(){
try {
in = serialPort.getInputStream();
receiveThread = new Thread(new SerialReader(in));
receiveThread.start();
receiveThread.join();
} catch (Exception e) {
}
}
public static void main(String[] args) {
try {
(new TwoWaySerialComm()).connect("COM3");
for (byte i = 0; i < 10; i++) {
output[i] = i;
}
output[10] = -1;
send(output);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SerialPort returnSerialPort(){
return serialPort;
}
}
If you want get int from your stream, it is easier with a BuffereInputStream and use the read() method which return a int -> no conversion needed.
Add this in your SerialReader class :
Thread.sleep(200);
BufferedInputStream input = new BufferedInputStream(in);
while ((value = input.read()) != 1 && index < 200)
{
compute(value);
index++;
}
input.close();
Don't forget to close() your stream when you have read all the data. This is more important when you write, because if you don't close() not all data are written (except if you flush() before).
I did not quite get the description.
But the answer to the Title on the question is here.
Convert InputStream to byte array in Java
From corsiKa's answer to Determine if a String is an Integer in Java, you can check if a String is a valid int like this:
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
// only got here if we didn't return false
return true;
}

Has anyone played with NIO pipes to filter / intercept System.out?

As suggested here I would like to do that inside the selector loop. What I would really want is to read contents written to system out inside my selector loop.
EDIT1: I coded a complete solution just to find out that you CANNOT redirect GC logs by using System.setOut. It simply goes straight to the FD or something. Show stopper! Unless I redirect to a file and pipe this file into my selector. Lots of work! See here.
One way to do it would be as follows:
create a subclass of OutputStream that redirects its output to a Pipe's sink channel
redirect System.out using this class: System.setOut(new PrintStream(new MyOutputStream(pipe));
register the pipe's source channel with a selector and get whatever was written to System.out in the selector loop, i.e. the source channel's correpsonding SelectionKey is selected as readable()
The following immplementation is a naive but working implementation, which simply redirects to System.err everything that is written to System.out:
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
public class SystemOutPipe extends Thread {
public static void main(String[] args)
{
try {
SystemOutPipe sop = new SystemOutPipe();
sop.start();
System.out.println("This message should be redirected to System.err\nNow waiting 5 seconds ...");
Thread.sleep(5000L);
sop.setStopped(true);
sop.join();
} catch (Exception e) {
e.printStackTrace();
}
}
private Selector selector;
private Pipe pipe;
private boolean stopped = false;
public SystemOutPipe() throws IOException {
super("SystemOutPipe");
pipe = Pipe.open();
System.setOut(new PrintStream(new PipeOutputStream(pipe)));
selector = Selector.open();
pipe.source().configureBlocking(false);
pipe.source().register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
#Override
public void run() {
try {
while (!isStopped()) {
int n = selector.select(1L);
if (n > 0) {
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (key.isReadable()) {
new ReadHandler(key).run();
}
}
}
}
} catch (Exception e) {
e.printStackTrace(); // writes to System.err !
}
}
public synchronized boolean isStopped() {
return stopped;
}
public synchronized void setStopped(final boolean stopped) {
this.stopped = stopped;
}
public class ReadHandler implements Runnable {
private final SelectionKey key;
public ReadHandler(final SelectionKey key) {
this.key = key;
}
#Override
public void run() {
ByteBuffer bbuf = (ByteBuffer) key.attachment();
ReadableByteChannel channel = (ReadableByteChannel) key.channel();
try
{
int count = 0;
do {
bbuf.clear();
count = channel.read(bbuf);
if (count > 0) System.err.write(bbuf.array(), 0, count);
} while(count > 0);
} catch (IOException e) {
e.printStackTrace();
key.cancel();
}
}
}
public class PipeOutputStream extends OutputStream {
private final Pipe pipe;
public PipeOutputStream(final Pipe pipe) {
this.pipe = pipe;
}
#Override
public void write(final int b) throws IOException {
write(new byte[] { (byte) b });
}
#Override
public void write(final byte[] b) throws IOException {
write(b, 0, b.length);
}
#Override
public void write(final byte[] b, final int off, final int len) throws IOException {
ByteBuffer bbuf = ByteBuffer.wrap(b, off, len);
bbuf.position(len);
bbuf.flip();
int count = 0;
while (count < len) {
int n = pipe.sink().write(bbuf);
if (n == 0) {
// let's wait a bit and not consume cpu
try {
Thread.sleep(1L);
} catch (InterruptedException e) {
throw new IOException(e);
}
}
else count += n;
}
}
}
}

Is this LimitedInputStream correct?

I've written a class called LimitedInputStream. It wraps around an existing input stream to limit the number of bytes read from it to a specified length. It's meant as an alternative to:
byte[] data = readAll(length);
InputStream ins = new ByteArrayInputStream(data);
Which requires the extra buffer.
This is the class:
public static class LimitedInputStream extends InputStream {
private final InputStream ins;
private int left;
private int mark = -1;
public LimitedInputStream(InputStream ins, int limit) {
this.ins = ins;
left = limit;
}
public void skipRest() throws IOException {
ByteStreams.skipFully(ins, left);
left = 0;
}
#Override
public int read() throws IOException {
if (left == 0) return -1;
final int read = ins.read();
if (read > 0) left--;
return read;
}
#Override
public int read(byte[] b, int off, int len) throws IOException {
if (left == 0) return -1;
if (len > left) len = left;
final int read = ins.read(b, off, len);
if (read > 0) left -= read;
return read;
}
#Override
public int available() throws IOException {
final int a = ins.available();
return a > left ? left : a;
}
#Override
public void mark(int readlimit) {
ins.mark(readlimit);
mark = left;
}
#Override
public void reset() throws IOException {
if (!ins.markSupported()) throw new IOException("Mark not supported");
if (mark == -1) throw new IOException("Mark not set");
ins.reset();
left = mark;
}
#Override
public long skip(long n) throws IOException {
if (n > left) n = left;
long skipped = ins.skip(n);
left -= skipped;
return skipped;
}
}
Use case:
Object readObj() throws IOException {
int len = readInt();
final LimitedInputStream lis = new LimitedInputStream(this, len);
try {
return deserialize(new CompactInputStream(lis));
} finally {
lis.skipRest();
}
}
for (something) {
Object obj;
try {
obj = readObj();
} catch (Exception e) {
obj = null;
}
list.add(obj);
}
Could you code review my class for any serious bugs, e.g. possible mistakes in updating left?
Guava includes a LimitInputStream, so you may want to just use that.

Categories