In Java, I want to intercept my process's stdout and stderr. I don't want to prevent it from going to the console/default destination eventually, but at every newline, I need to copy that line into my own log file (with some formatting and HTMLification). The only way I can see to do this is something like this -- which might work, but I'm worried about different charsets, want to eventually format output the same way as before instead of suppressing it, and I need to handle it at every newline, not when it feels like flushing (even with auto-flush = true).
Is there a library of some sort that makes this easier?
but at every newline, I need to copy that line into my own log file (with some formatting and HTMLification).
Why don't you consider the classic Unix utility tee? A demo:
tail -f source | tee tee.sink
echo "foo" >> source -- you should see "foo" also on your terminal
cat tee.sink should display foo.
Or did I misunderstand what you want?
Related
In Java, newly created output streams look at the system line separator property to decide between Unix and Windows line endings, but System.out has already been created by the time your program starts, so altering that property has no effect on that stream.
If you want System.out to use Unix line endings, despite running on Windows, is there a way to do this other than eschewing println() and always using print("...\n")?
You can manually set System.out. I sometimes use it to redirect prints to a file.
For example:
System.setOutput(new PrintStream("whatever_file.txt"));
In a similar sense, you can change the PrintStream to take your line endings into account.
Alternatively you can directly set the property of the line ending character:
System.setProperty("line.separator", "\n");
This could also be done when creating the JVM by the usual property setter:
java -jar bla.jar -Dline.seperator='\n'
I am reading different files from different operating systems.
In file there are lots of lines. but i got info that after every line there may be use "\n" or "\r" or something like that.
When i read file by following instructions from Best way to read a text file [closed]
then what should i add to print in console by if-else conditions which explain in Class Pattern.
I need help please.
I am trying by reading this. But still need experts help.
Thanks.
If you're just printing to the console, you can simply use \n. To give you a little background, the times where those two separators really matter is within the files themselves (and when you must manually detect or write newlines in a file). In a unix-based system, newlines are represented in files by \n. In Windows, newlines are represented by \r\n. But when you are printing to the console, \n will perform correctly.
Also in the pattern matching example you gave. You're simply manually adding a newline so you can tell where a newline is. So especially in that case, you can mark the newline however you want as long as it's consistent.
what is the difference when I use buffer istead of console() for retriving the output from my code?
The Console class, as used by System.console() seems targeted to interactive character-based I/O, as provided by an actual console such as a cmd.exe window in Windows or a terminal in Unix-like systems. As such, the system console may not always be available, depending on the underlying OS and how the JVM was started.
On the other hand, Scanner works with any input stream, including files and the standard input. It is more flexible, but it does not provide some console-specific functionality that Console does, such as the ability to read text - usually passwords - without echoing it back to the console.
The Console class makes it easy to accept input from the command line, both echoed and unechoed. Unechoed means you will see some special character in your console while writing a text (ex. *, ? etc) like when you enter your password in facebook. :) Its format() method also makes it easy to write formatted output to the command line(like making a pyramid of *s or a formatted date and currency formats etc). It also helps to write test engines for unit testing. or you can use it to provide you a simple CLI (Command Line Interface) instead of a GUI (Graphical User Interface) in case you want to create a real simple and small application. And yes, it is also system dependent that means that you cannot always rely on your system to provide you a console instance.
Now about buffering, its actually a technique used in I/O (i.e. both input and output) when you are interacting with a stream (be it a character stream or byte stream, be it from a console or a socket or a file). Its basically used to speed up the I/O and save system resources by avoiding multiple call to read() and write() methods. It is suggested that you use it in almost every kind of I/O interaction.
I've read some posts on stackoverflow about this topic but I'm still confused. When reading a file that is currently being written in Java, how do you keep track of how many lines have actually been written so that you don't get weird read results?
EDIT: sorry, I should have mentioned that the file writing it is in C++ and the one reading it is in Java so variables can't really be shared easily
When reading a file that is currently being written in Java, how do you keep track of how many lines have actually been written so that you don't get weird read results?
The problem is that you can never be sure that the current last character of the file is the end of a line. If it is a line terminator, you are OK. If BufferedReader.readLine() will interpret it as a complete line without a line terminator ... and weird results will ensue.
What you need to do is to implement your own line buffering. When you get an EOF you wait until the file grows some more and then resume reading the line.
Alternatively, if you are using Java 7 or later, the file watcher APIs allow you to watch for file writes without polling the file's size.
By the way, there is an Apache commons class that is designed for doing this kind of thing:
http://commons.apache.org/io/api-2.0/org/apache/commons/io/input/Tailer.html
If I understand, the file is being written in C# in some process and another Java process wants to read it while it is being written.
Look at File Monitoring section on the tail command here. But I want to warn you that when I used the cygwin tail on Windows recently to follow log files that were rolling over, it sometimes failed under heavy load. Other implementations may be more robust.
To have a count of the number of lines, just keep a counter on the side that's doing the writing.
So, every time you write a line, increment a counter, and make that counter readable via a method, something like, public int getNumLinesWritten()
The obvious answer to me... Why not use a buffer? Use a string or whatever you need. (You could use a list/array of strings if you want, one for each line maybe?) Append to the string just as you would write to the file, then instead of reading from the file, read from that string. Would that work for you?
I'd like to solve following issue: imagine that you are doing lots of outputs in System.out, and from time to time there is an Exception thrown. When you look into the console, you can see that the exception's trace text is mixed up with normal output done by System.out. I understand that these two are different streams (System.out and System.err) and I guess that the output of the exception is done internally by some other thread, that is why it is mixed up.
However, is it somehow possible for the code to stop until output for the exception is done? The only solution I can think of is to put Thread.sleep, but maybe there might be some option I am not aware of.
Just curious really :) It'd be nice for debugging (that's the reason I ask, because reading the output and exceptions mixed up in between is terrible)
If you have multiple threads and their output is getting interleaved, you should think about using a logging facility rather than trying to share the stderr and stdout-
http://download.oracle.com/javase/6/docs/api/java/util/logging/package-summary.html
Or apache's log4j:
http://logging.apache.org/log4j/1.2/
How about redirecting System.err to a file?
System.setErr( ... );
The problem needs to be solved elsewhere, in the process which merges two file streams into the output you see - by only printing out a line when it is done. Since that is most likely not an option to you if you are talking about the "java.exe" output, you need to investigate elsewhere.
I have not tested, but I would start with having a look at invoking flush() on System.out before you send output to System.err.
When java implicitly imports the lang (java.lang.*) package, the System class has 2 standard output streams.
System.err
System.out
And because these both output to the same standard output, you have to choose one and change it from standard output to file output. My recommendation would be to change the System.err output like so:
import java.io.* ......
System.setErr (new PrintWriter (new FileWriter ("Errors.txt")));
Hope this helps!
EDIT
Sorry, can't leave comments yet, but the logging idea above is very good. Depending on what you are doing, logging will be an optimal solution. But I try to avoid logging because it tends to become very memory extensive if it is used too much.
Write to a separate stream in memory to format your output, then write the single string at once. You may still end up with your single string in the middle of an exception's text, though. Fundamentally what you are doing requires synchronization, or a separate stream (think one output file per thread).
I don't see how Thread.sleep will do anything other than complicate the issue.
Create a new PrintStream to file descriptor 2 with autoflush set to false.
System.setErr(new PrintStream(new FileOutputStream(FileDescriptor.err, false, "UTF-8")));
Just make sure to call System.err.flush after important error messages.
If you want to merge stderr into stdout, you can do the above but with FileDescriptor.out.