Console output to file using multithreading - java

Is there a way to save the whole console output to a file when multithreading? I'm working with 5 threads. I had this idea that i can put a printstream in the run-method.
example:
public void run() {
try{
PrintStream out = new PrintStream(file);
stopExecute stop = new stopExecute();
Thread t = new Thread(stop);
Scanner in = new Scanner(System.in);
t.start();
while (!in.hasNextLine())
{
classThatUsingMultipleThrads();
System.out.println("Finished");
anotherClassThatUsingThreads();
System.out.println("Finished");
}
System.out.prinln("User stopped the execution");
stop.keepRunning = false;
System.setOut(out);
}
catch(IOException e){System.out.println(e);}
Problem here is that it's only saving the output "User stoped the execution" and everything in the whileloop are not saved. Or the outputstream from other classes.
I've tried to put the
System.setOut(out);
in the while-loop, but didn't help.
Edit: Spell correction

try {
System.setOut(new PrintStream(new File("output-file.txt")));
}
catch (Exception e) {
e.printStackTrace();
}
thanks to: System.out to a file in java

You should probably look into using a logging library such as Log4J. However you could also use something like a TeeOutputStream. This type of output stream writes to 2 other streams when called. A few libraries have great implementations but you can also write one yourself. I whipped this one up real quick.
You could set the output stream for your entire program in your main method to use this TeePrintStream, then all calls to System.out.* will write data to the usual System.out and your FileOutputStream.
Theres also an implementation of the TeePrintStream here http://www.java2s.com/Code/Java/File-Input-Output/TeePrintStreamteesallPrintStreamoperationsintoafileratherliketheUNIXtee1command.htm
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
public class SO34042494 {
public static void main(String[] args) throws FileNotFoundException {
System.setOut(new TeePrintStream(System.out, new FileOutputStream(new File("x:\\output.txt"))));
System.out.println("Check check");
System.out.println("1");
System.out.println(2);
System.out.println(3L);
}
public static class TeePrintStream extends PrintStream {
private final OutputStream tee;
public TeePrintStream(PrintStream original, OutputStream tee) {
super(original);
this.tee = tee;
}
#Override
public void write(byte[] b) throws IOException {
super.write(b);
tee.write(b);
}
#Override
public void write(byte[] buf, int off, int len) {
super.write(buf, off, len);
try {
tee.write(buf, off, len);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
#Override
public void write(int b) {
super.write(b);
try {
tee.write(b);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
#Override
public synchronized void close() {
try {
tee.close();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
super.close();
}
}
}
}
The TeePrintStream I have here is something I just threw together, please if your going to use this in a production project polish it up and test it thoroughly

Okej i think i solved it. In my main i just did like this:
public static void main(String[] args) {
Prinstream out = new Prinststream(file);
/*
Do some things like start threads, call objects etc..
.
.
.
.
*/
System.setOut(out);
I think that when all threads are started and doing their things(i do assign a object to each thread) the printstream will catch every console-output that occurs in other classes.
This didn't work before i edited my stopExecute class.
public class stopExecute implements Runnable {
Scanner scan = new Scanner(System.in);
private Object[] obj;
public stopExecute(Object[] obj)
{
this.obj = obj;
}
public void run() {
while(true){
stop();
}
}
public void stop() {
if(scan.hasNextLine()){
System.out.println("Stopped");
System.exit(0);
}
}
}
Thank you for your help guys. I will look into your suggestions and try them. In this solution i'm unable to use Log4J. But i will definitely check it out.

Related

reading file using BufferedInputStream

I am new to Java programming and I was reading the a file using the BufferedInputStream(). Can someone tell me why I can't read my file? If I print obj.read(), it returns -1 everytime. Instead it should return the unicode value of every character that the stream is reading.
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
public class Main {
public static void main(String[] args) {
try {
FileInputStream obj = new FileInputStream("myfile.txt");
BufferedInputStream obj2= new BufferedInputStream(obj);
while(obj2.read()!=-1)
{
System.out.print((char) obj2.read());
}
}
catch (Exception e)
{
System.out.println(e);
}
System.out.println("program executed");
}
}
But after introducing a local variable the code works, why???
package com.company;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
public class Main {
public static void main(String[] args) {
try {
FileInputStream obj = new FileInputStream("riten.txt");
BufferedInputStream obj2= new BufferedInputStream(obj);
int a;
while((a=obj2.read())!=-1)
{
System.out.print((char)a);
}
}
catch (Exception e)
{
System.out.println(e);
}
System.out.println("program executed");
}
}
You need to read from your BufferedInputStream and not from the FileInputStream. You are mixing things here.
But in addition to your code you need to properly handle streams, i.e. when you open a file you need to close those afterwards.
A fix of your code. I added a local variable to store the read character and then cast it to a character.
public static void main(String[] args) {
try {
FileInputStream obj = new FileInputStream("myfile.txt");
BufferedInputStream obj2= new BufferedInputStream(obj);
int c;
while((c = obj2.read())!=-1)
{
System.out.print((char) c);
}
}
catch (Exception e)
{
System.out.println(e);
}
System.out.println("program executed");
}

Java problems w/ printing in new thread

I have my code setup so that when a long process is happening on the main thread of my Java program, another thread is opened to show a loading animation on the console, but this isn't working and the loading animation just prints all at once after the thread is closed. BUT it works if I use println() instead of print(), then the dots are printed every 200 milliseconds while the thread is running as expected but I need them to be printed on the same line. See code below.
Main thread:
Thread animate = new Thread(new ConsoleAnimator(".",200));
animate.start();
//do stuff for a few seconds
animate.interrupt();
Secondary thread:
public class ConsoleAnimator extends Thread{
public int animateInterval;
public String animateString;
public ConsoleAnimator(String toAnimate, int interval){
this.animateInterval = interval;
this.animateString = toAnimate;
this.setPriority(Thread.MAX_PRIORITY);
}
public void run(){
try{
while(true){
Thread.sleep(animateInterval);
refresh();
}
} catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
void refresh(){
System.out.print(animateString);
System.out.flush();
}
public void interrupt(){
System.out.println();
super.interrupt();
}
}
Would appreciate any help, thanks
The System.out is line buffered. There needs to be a newline before it's outputted to console.
If you need it to remain on the same line you could choose to use Use System.err that should work for your purposes.
If you rewired stderr to another output like file you could write your own console output.
See it in action: https://ideone.com/mlyPdx
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new
FileOutputStream(FileDescriptor.out), "ASCII"), 512);
out.write("test");
out.flush();
out.write(" > ");
out.flush();
out.write("string");
out.flush();
This is the code that runs on my sytem, windows 7 and cmd
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
public class Test
{
public static void main (String[] args) throws java.lang.Exception
{
Thread animate = new Thread(new ConsoleAnimator(".",200));
animate.start();
for(int c =0; c < 20; c++) {
Thread.sleep(1000);
}
animate.interrupt();
}
}
class ConsoleAnimator extends Thread{
public int animateInterval;
public String animateString;
protected BufferedWriter out;
public ConsoleAnimator(String toAnimate, int interval) throws IOException {
this.animateInterval = interval;
this.animateString = toAnimate;
this.setPriority(Thread.MAX_PRIORITY);
this.out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileDescriptor.out), "ASCII"), 512);
}
public void run(){
try{
while(true){
Thread.sleep(animateInterval);
refresh();
}
} catch(InterruptedException e){
Thread.currentThread().interrupt();
}
catch( Exception e) {
Thread.currentThread().interrupt();
}
}
void refresh() {
try {
this.out.write(animateString);
this.out.flush();
}
catch(IOException ex) {
}
}
public void interrupt() {
try {
this.out.write(System.lineSeparator());
this.out.flush();
}
catch(IOException ex) {
}
super.interrupt();
}
}
Why not use some libs such as progressbar, java-progressbar?
If you want to know why your code does not work, you can look up the code of these libs.

Jline input disrupted by System out

I'm having some trouble with Jline and not quite understanding how to work it properly, everything seems to work from the examples but when i attempt to move it into my console application things go weird.
I've come across two issues:
When you write input into the console while something else is logging a message via System out, the written input gets broken. (View: https://i.imgur.com/ZAJDjTI.png)
I attempted to sync the commands to the main thread since the reader thread will be blocking, but this time you'll find that this causes the output text to take over the commands input space.
((Green text is the input, white is output)View: https://i.imgur.com/CdKiIYy.png)
The output i expected was for input coming from the bottom of the console to be unaffected by the output of the console, leaving a smooth input text layer at the bottom. (View: https://i.imgur.com/HfH5l8U.png?1)
Here's an example class i wrote to demonstrate the two problems I'm having:
import jline.console.ConsoleReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.ReentrantLock;
public class Example {
private ConsoleReader consoleReader;
private LinkedList<Runnable> syncQueue = new LinkedList<>();
private ReentrantLock lock = new ReentrantLock();
public Example() {
try {
this.consoleReader = new ConsoleReader();
this.consoleReader.setExpandEvents(false);
} catch (IOException e) {
e.printStackTrace();
}
//If you enable this, Jline seems to be disrupted by the System out.
// startStopwatch();
setupJline();
//Ticker, its ugly i know
while (true) {
lock.lock();
try {
while (syncQueue.size() > 0) {
Runnable runnable = syncQueue.poll();
try {
runnable.run();
} catch (Exception e) {
e.printStackTrace();
}
}
} finally {
lock.unlock();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void setupJline() {
new Thread("Console Thread") {
#Override
public void run() {
while (true) {
try {
String line = consoleReader.readLine(">");
if (line != null && line.trim().length() > 0) {
//Lets pass this on as an instruction to our program
//Sync seems okay, output wise
handleInstructionSynced(line);
//async seems to mess things up though, comment the handleInstructionSynced method and
//uncomment the Async one to see what i mean.
//handleInstructionAsync(line);
}
consoleReader.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}
//Just a dummy example instruction handler
private void handleInstructionAsync(String input) {
System.out.println("You've input \"" + input + "\" as your instruction.");
}
private void handleInstructionSynced(String input) {
runSync(() -> System.out.println("You've input \"" + input + "\" as your instruction."));
}
private void runSync(Runnable runnable) {
lock.lock();
try {
syncQueue.add(runnable);
} finally {
lock.unlock();
}
}
private void startStopwatch() {
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
int time = 0;
#Override
public void run() {
System.out.println(time + " seconds counted");
time++;
}
};
timer.scheduleAtFixedRate(timerTask, 0, 1000);
}
public static void main(String[] args) {
new Example();
}
}
Any solutions?

IOException handling in multiple methods

Consider the following code
public class foo {
public static void main(String[] args) {
MyClass mc = new MyClass();
mc.read();
}
}
and
public class MyClass {
private BufferedWriter verb;
private String vFile;
MyClass()
{
try {
verb = new BufferedWriter(new FileWriter(vFile));
} catch(IOException e) {
System.out.println("Internal error1");
System.out.println(e.getMessage());
}
}
public void read()
{
// read a file and create an array
verb.write("Array created"); // ERROR
}
}
As you can see the write is not placed in a try..catch block. I can write a catch for that, but MyClass has many methods and verb.write is used heavily. I also can write public void read() throws IOException to throw the exception to the the caller, main(). Still I have to put mc.read() in a try..catch block. Since MyClass has numerous methods, then I have to put all of them in a catch block in the main().
So, is there a better way to handle that? Is it possible to redirect all exceptions related to verb to the constructor, MyClass() where a try..catch is defined?
One approach is to make your own "safe" wrapper around BufferedWriter (for that matter, any kind of Writer) and handle I/O errors there:
class SafeWriter {
private final Writer writer;
public SafeWriter(Writer writer) {
this.writer = writer;
}
public void write(int n) {
try {
writer.write(n);
} catch (IOException e) {
handleException(e);
}
}
public void write(String s) {
try {
writer.write(s);
} catch (IOException e) {
handleException(e);
}
}
... // Provide wrappers for other methods here
private void handleException(IOException e) {
...
}
}
Now you can use write methods on your new class to handle exceptions in a uniform way inside the class:
private SafeWriter verb;
...
verb = new SafeWriter(new BufferedWriter(new FileWriter(vFile)));

java rxtx SerialWriter issue

I am using RXTX to communicate between JAVA and a microcontroller.
This is the JAVA code for opening a connection, sending and receiving data
package app;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class SerialCommunication1 {
private static SerialCommunication1 instance = null;
private static boolean coonected = false;
public static SerialCommunication1 getInstance(){
if(instance == null)
instance = new SerialCommunication1();
return instance;
}
private SerialCommunication1() {
super();
try {
connect("COM4");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SerialCommunication1.coonected = true;
}
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 = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_2, SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
} else {
System.out
.println("Error: Only serial ports are handled by this example.");
}
}
}
/** */
public static class SerialReader implements Runnable {
InputStream in;
public SerialReader(InputStream in) {
this.in = in;
}
public void run() {
byte[] buffer = new byte[1024];
int len = -1;
try {
while ((len = this.in.read(buffer)) > -1) {
System.out.print(new String(buffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** */
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0){
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And this is the Java code that is calling when an event triggers
SerialCommunication1.getInstance();
if(ledStatus == true) {SerialCommunication1.SerialWriter.str = "4A01";}
else {SerialCommunication1.SerialWriter.str = "4A00";}
stopProcess();
And now the problem. I need to send a command to my microcontroller with the code 4A01 and, after receiving the answer, I need to call it again with the code 4A00. The calls are triggered by a button from my Java interface. The problem is that the second call is not executed (4A00 is not sending). I tried to inverse the command codes and they work well. After the first one (4A01) is executed, my microcontroller reacts and sends the response which is read by java and my interface is updated. When I send the invers command (4A00) it stops exactly at this line SerialCommunication1.SerialWriter.str = "4A00"; and doesn't even enter inside the SerialWriter's run() method.
Do you have any idea why is this happening? From the side of my microcontroller there is no problem, I checked all the possibilities with a tool.
I hope I made myself clear.
Thank you!
LE: I forgot to tel you that it didn't throw any errors or exceptions
I'm not sure because I'm not able to test your code but I think your problem is in SerialWriter class:
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null; // Here str is initialized to null
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0) { // this should throw NPE because str is null
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Since there is no loop in this method, then the thread created within SerialCommunication1 at this line:
(new Thread(new SerialWriter(out))).start();
most likely finishes its execution after sending the first str.
Honestly I don't understand how does it even send a single string, since str is initialized to null in first place and it should throw NullPointerException at str.length() line.
I would suggest you this approach:
Don't trigger a writer thread when connection is established, just trigger a new one every time a message will be sent.
Use Singleton pattern correctly.
Keep a reference to the serial port in SerialCommunication1 class.
Translated to code it would be something like this:
class SerialWriter implements Runnable {
OutputStream out;
String message;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void setMessage(String msg) {
this.message = msg;
}
public void run() {
try {
if(message != null) {
this.out.write(str.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then in SerialCommunication1 class add this public method:
public void sendMessage(String msg) {
SerialWriter writer = new SerialWriter(serialPort.getOutputStream()); // of course you'll have to keep reference to serialPort when connection is established
writer.setMessage(msg);
(new Thread(writer)).start();
}
And finally call this method in this way:
SerialCommunication1.getInstance().sendMessage("4A01");
tzortzik,
I think tha is a timeout problem. Try to addding a delay to writer :
/** */
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
Thread.sleep(500); //<----------- this should be in mainThread before to SerialWriter.start();
System.out.println("Will try to execute");
try {
if(str.length() > 0){
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
It happens to me many times, "we should learn to wait for a response" (^_^)
Check if you are executing well a secuence like the next:
Send command 4A01
Receive response 4A01 from micro
WAIT FOR RESPONSE BEFORE SEND SECOND COMMAND. Thread.sleep(500); //wait for 500 milis or more
Send command 4A00
Receive response 4A00 from micro
I hope it could help you.

Categories

Resources