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.
Related
I wrote multithreaded java server-client sockets app with messaging functionality but I encountered a problem with simultaneous console IO.Main server console is listening for keyboard input and simultaneously printing out messages from the clients. On client side there is a separate thread for printout.
Here is simplified code representation:
public class ServerThread{
....
BufferedReader in = ... (sock.getInputStream);
while(true){
System.out.println(in.readline());
....
public class ServerMain{
.....
BufferedReader keyb = ... (System.in);
while(true){
in = keyb.readLine();
....
The problem occurs while I'm typing something in the main server console and at the same time a message arrives from one of the clients.
That message is then concated to what I was typing on screen and cursor moves to the beginning of the next line waiting for input.
What was typed in previously is stuck in the keyboard buffer, and I cant edit it anymore. Same problem happens on client side.
The question is how can I print messages on screen without disrupting ongoing input?
(inputted text also needs to stay printed on screen as in readLine() default behavior)
I already tried some of the solutions suggested for other similar problems:
In Lanterna and JCurses libraries there's no support for native System.IO streams. I would have to reinvent the wheel and implement it all by myself manually from memory to screen, one char at a time plus build whole console GUI layer.
The other thing was using ANSI codes but I couldn't figure out how to do what I need with them. I could read one input char at a time instead of a whole line, then if message arrives clear the line, move cursor to the beginning and printout, but afterwards in nextline I don't know how to print previously buffered text and still be able to delete chars with backspace.
edit:
GUI is not an option as I want my code to be able to run on a headless server.(also assume that there will be only one terminal, console, shell, and app running per side)
A distinct non-answer, based on: there is only one console.
And that console is an artefact from times when multiple threads weren't a real problem. "Works nicely with multiple threads" was never a requirement for that low level console.
Thus: if you really want a sophisticated solution (that isn't a hack of some sort) simply consider: not using the stdin/stdout console(s).
Instead: write a simple Swing GUI application. Have one text entry field where input is collected, and one or maybe multiple text fields where your output goes. If you want to be fancy, make it a webapp. I am sure that using some framework, you could put together a working thing within a few hours. You will learn more valuable skills by doing that, instead of spending these hours "working around" the fact that you picked the wrong technology for your problem.
Update, given the comment by the OP: then the best I can think of: don't write to the console. Write to different files. Open multiple terminals, and use tools like "tail" to show you what is happening with your output file(s).
Ok, I found the ideal solution myself:
JLine library works in conjunction with default System.IO, also there is no need to create new Terminal objects (you can) or anything else. Simply instead of BufferedReader you use LineReader
String readLine(String prompt, Character mask, String buffer)
prompt (can be null) is the unexpanded prompt pattern that will be displayed to the user on the left of the input line
mask (can also be null) is the character used to hide user input (when reading a password for example)
buffer is the initial content of the input line
Edit: In JLine's docs i found an even better solution:
printAbove
void printAbove(AttributedString str)
Prints a string before the prompt and redraw everything. If the LineReader is not actually reading a line, the string will simply be
printed to the terminal.
Parameters:
str - the string to print*
I am very much confused about Streams.
1) Does OS(i.e Windows) provide a Common Standard Input Stream and all the languages use it(i.e. Java refers to it as System.in and same Standard Input Stream is referred with stdin in c)?
Is it like keyboard has some port or physical address and OS has stored that
in some variable and when a program needs that it will give that same address to stdin or System.in depending on the language?
OR,
2) Is it like each language has its own API written for standard streams and when we run the program, a stream will get connected to the input device?
And what information that stream would have apart from data? i.e. Physical Port or address of device or what?
Also, Please tell about what is the meaning of System.in get "connected" to program when we run it. what does "connected" mean here?
Please share some link.
Definitions
A “stream” is a catch-all word, like “window”. All a stream means is that there is some thing (a “device”) that produces sequential data or accepts sequential data.
For example, I can make a string into an input stream (produces data), by simply keeping track of what the next character to produce is. When we run out of characters, we've reached the end of the stream. C++:
struct my_hello_stream
{
static const char* s = "Hello world!";
int n;
my_stream(): n(0) {}
int get()
{
if (s[n]) return s[n++];
return EOF;
}
};
Abstractions
Every system has its own way of abstracting a stream. The OS does it through files, pipes and character devices, which you can open for reading or writing. How exactly this is done depends entirely on the design of the OS. Consult your OS API documentation.
On top of that sits a programming language, like C or C++ or Java or FORTRAN — you name it. The programming language itself also defines a stream in a way convenient for the users of that language. In C you have a FILE*. In C++ you have std::iostreams. In Java you have I/O streams. Whatever the case, this works above the OS stream to read and write data from and to files, etc.
Moreover, these language features often allow you to do more powerful things with these stream interfaces, such as convert the character sequence 1234567 into a native integer value, and to perform these operations over strings.
Beyond that, there are also external libraries that allow us to treat things like internet connections and port connections with the printer like a stream. Some of this stuff the OS handles for us. Some of it it doesn't.
tl;dr
It all depends. What matters is the abstraction you have access to — which is typically your programming language. Hence, read about how your programming language expects you to open a file and read and write data, then act as if that is right. Whatever else actually happens underneath is magic.
What is a stream?
Stream is an abstraction which is either an input source or an output destination. In UNIX for example everything is a file so your keyboard will be represented by a read only file (why?). Whenever you want to read something from keyboard you just use the read system call using the keyboard file as parameter.
Does OS(i.e Windows) provide a Common Standard Input Stream and all
the languages use it(i.e. Java refers to it as System.in and same
Standard Input Stream is referred with stdin in c)?
OS only provides the very basic functionality such as read and write system calls (OS dependent) which can be used to read and write raw bytes. All the programming languages use this basic functionality to create abstractions (such as translating raw bytes to certain character set or buffering the data before writing).
When the program starts executing operating systems opens three standard text stream (channel) automatically and provides constant file pointer for them.
The stream you can think as like a channel, rather than a standard stream we have to open a stream by some library functions like fopen in c, which creates a stream bw your program and the file specified.
I have a program that needs to process data from Standard-In. I can call it on the command line like so java program < input. I want to write a proper unit test for its main(). Is it possible to reassociate a method's System.in with some other stream?
In the test, I can read the sample data, and then somehow run the original program with its stdin connected to some stream that i define (from the sample data) and verify that it returns what i expect. I considered using these classes:
PipedInputStream and
PipedOutputStream. But it would require me to modify the original program to read from a PipedInputStream every time I test it. Or I can isolate the stream reading into a function (eg. parseStream(InputStream) ) and pass a PipedInputStream which is already connected to the sample data.
I can also write a shell script to pipe whatever i want into its stdin, but the method in question will be a part of a series of processing steps so it shouldn't itself write to stdout and actually returns ArrayList<SomeCompositeType>. Where SomeCompositeType contains the data that was read in a structured way (eg. some ints, arrays, Maps, etc..)
So is it possible to call some method that reads from System.in with a different stream?
See my comment.
What you appear to want is provided by System.setIn :-)
On standard console all things are printed in white whether we have written it in System.out or System.err. In IDE(for me Eclipse) we can see different color output on console for both. i.e. black for System.out and red for System.err.
Is System.err is only provided for use in IDEs? Cause on cmd we can not distinguish System.out and System.err. Both are printed in same color.
These are two different output streams that are available in most of OS's. You don't have them color coded due to settings of your terminal/command line environment. On the other hand your IDE provides different visualization for different streams.
If you wanted to color them, consider using ANSI escape sequences.
This is a relict from the unix world, where most functionality is available as unix commands which were intended to be chained. The output of one command is used to feed another like here:
grep -i 'token' file | mail peter#address.de
The pipe symbol only redirects the stdout (System.out), but not the stderr (System.err). So error messages would be seen on the console, and the regular output would go to the mail command.
If there were just one stream, one could not distinguish between them.
Windows, not relying on the command line (This changed in Windows Server 2008!) didn't invent again but just took the unix concepts and made them available in their dos commands, too. It is just that nearly no Windows only users usually know what they are good for.
From system-in-out-error:
System.err is a PrintStream.
System.err works like System.out
except it is normally only used to
output error texts. Some programs
(like Eclipse) will show the output to
System.err in red text, to make it
more obvious that it is error text.
From JLS:
20.18.3 public static PrintStream err;
The initial value of this variable is
a "standard" error output stream,
already open and ready to accept
output data. Typically, this
corresponds to display output or
another output destination specified
by the host environment or user. By
convention, this output stream is used
to display error messages or other
information that should come to the
immediate attention of a user even if
the principal output stream, the value
of the variable out, has been
redirected to a file or other
destination that is typically not
continuously monitored. Note that this
field is not final, so its value may
be updated if necessary.
From Java World 02-qa-1220-console.html
Other post in Stackoverflow coloring-text-with-java-in-windows
System.out goes to the standard output stream (stdout) and System.err goes to the standard error stream (stderr). See standard streams for details and how you can control where they go. Eclipse just conveniently colour codes them for you so you can distinguish them in one view.
Both System.out and System.err always exist in Java.
Depending on your console it might be possible to get it to display the two streams in a different colour.
Example use:
try {
Class.doSomething(myFile);
} catch (Exception e){
System.err.println("Fatal error performing doSomething: " + e);
System.exit(-1);
}
I'm using the Scanner class to take some input from the user through the console. Whenever the user inputs something in the screen and presses enter the input stays on screen for example:
This is the prompt
// User writes command and presses enter
command
output of command goes here
//Use writes command3
command
output of command goes here
command3
output of command3 goes here
Is there anyway I can make the command entered not stay in the console after pressing enter?
For example:
//User writes command
output of command goes here
Short answer: no, not from directly within Java. Java has very limited control over the console: you can only read and write to it. Whatever is displayed on the console cannot be erased programmatically.
Long answer: in Java, all console operations are handled through input and output streams—System.in is an input stream, and System.out and System.err are output streams. As you can see for yourself, there is no way to modify an output stream in Java—essentially, all an output stream really does is output bytes to some destination (which is one reason why it's called a "stream"—it's one-way).*
The only workaround I can see is to use a Console object (from System.console()) instead. Specifically, the readPassword() method doesn't echo whatever the user types back to the console. However, there are three problems with this approach. First of all, the Console class is only available in Java 1.6. Second, I wouldn't recommend using this for input other than passwords, as it would make entering commands more troublesome than it's supposed to be. And third, it still wouldn't erase the prompt from the screen, which would defeat the purpose of what you're trying to achieve, I'd think.
* - Technically speaking, System.out and System.err are both instances of PrintStream, but PrintStream is pretty much just a flexible version of OutputStream—a PrintStream is still like a normal output stream in that outputting is a one-way operation.
You will struggle to do this with the standard library.
If you don't want to do it yourself, you may be able to do this with a 3rd party library like JLine.
huh - I always assumed that if you sent backspace characters ('\b') to sysout that it would clear - but I never actually tried it (don't do much console programming these days).
Haven't tried that, but the bottom of this thread seems to indicate that it should work.
Note that this might not work in an IDE console, but may work in a regular OS console...
I'll leave actually proving for certain that it works as an exercise to the OP :-)