why we use system.out.flush()? [duplicate] - java

This question already has answers here:
When/why to call System.out.flush() in Java
(4 answers)
Closed 9 years ago.
Can someone please explain why we we would use system.out.flush() in a simpler way? If there could be a chance of losing data, please provide me with an example. If you comment it in the code below nothing changes!
class ReverseApp{
public static void main(String[] args) throws IOException{
String input, output;
while(true){
System.out.print("Enter a string: ");
System.out.flush();
input = getString(); // read a string from kbd
if( input.equals("") ) // quit if [Enter]
break;
// make a Reverser
Reverser theReverser = new Reverser(input);
output = theReverser.doRev(); // use it
System.out.println("Reversed: " + output);
}
}
}
Thank you

When you write data out to a stream, some amount of buffering will occur, and you never know for sure exactly when the last of the data will actually be sent. You might perform many
operations on a stream before closing it, and invoking the flush() method guarantees that the last of the data you thought you had already written actually gets out to the file.
Extract from Sun Certified Programmer for Java 6 Exam by Sierra & Bates.
In your example, it doesn't change anything because System.out performs auto-flushing meaning that everytime a byte in written in the buffer, it is automatically flushed.

You use System.out.flush() to write any data stored in the out buffer. Buffers store text up to a point and then write when full. If you terminate a program without flushing a buffer, you could potentially lose data.

Here is what the say documentation.

Related

Ignore earlier input when reading from console

I want to output a question to the console and then get the next line of input after the question was output.
For example, my program could be sleeping or doing some time-consuming computation, and while the user is waiting they might decide to type some notes into the console (perhaps without hitting enter, or perhaps over several lines). Once the sleep is completed, the program then asks the user a question, "What is your name?" and then it should wait for the next line of input containing the user's name, and ignore any random notes the user made while the sleep was going on.
Here's some code that tries to do that:
public static void main(String[] args) throws InterruptedException {
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
System.out.println("What is your name?");
// while (scanner.hasNext()) {
// scanner.nextLine();
// }
String name = scanner.nextLine();
System.out.println("Hi, " + name);
}
This behaves as follows when I type a couple of lines during the sleep:
gpeo
hpotWhat is your name?
Hi, gpeo
The problem is that scanner will read the next input continuing from the last input it read, not from the last System.out.println() (which makes sense). The commented out code tries to rectify that problem by reading past all earlier input first, then waiting on one more line to assign to name. However, scanner.hasNext() does not work as I was hoping, since when there is no next token it does not simply return false but waits for another token (so I don't know why it bothers to return a boolean at all).
Another thing that baffles me is that during the sleep if you type stuff on a single line, that single does in fact get ignored:
brbr irgjojWhat is your name?
A
Hi, A
I thought it was going to output Hi, brbr irgjojA, so that makes me think I might be misunderstanding how console input and Scanner work.
Edit: The last example was from a run within IntelliJ. When I run from my Bash commandline instead I get Hi, brbr irgjojA. The output of the first example does not change though.
Also, I was asked if this question is the same as this, and apparently I have to explain why it's not here or it will appear on the question. The issue in that post (and others like it) is that he/she is mixing scanner.nextLine() with scanner.nextInt() and similar methods that do not read the whole line or the line ending. I am only using nextLine() to read input, and my issue is quite different.
Further edit
I managed to discard the first line of random notes based on this answer to another question. Here is the new code:
public static void main(String[] args) throws InterruptedException, IOException {
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
System.out.println("What is your name?");
while (System.in.available() > 0) {
scanner.nextLine();
}
String name = scanner.nextLine();
System.out.println("Hi, " + name);
}
Here are some test runs in IntelliJ:
grgWhat is your name?
A
Hi, A
ghr
rhWhat is your name?
A
Hi, A
rghr
hrh
htWhat is your name?
Hi, hrh
uirh
iw
hjrt
sfWhat is your name?
Hi, iw
And here are similar tests in Bash:
htrWhat is your name?
A
Hi, htrA
rgj
hrWhat is your name?
A
Hi, hrA
rjkh
ry
jWhat is your name?
Hi, ry
ryi
rj
rd
jrWhat is your name?
Hi, rj
As you can see, the line inside the while loop never appears to get executed more than once for some reason. I tried adding a sleep inside the loop or using other InputStream methods like skip() and readAllBytes(), but these didn't seem to help at all.
I think there might not be anything one can do about the incomplete line that is a problem for Bash, but I'm sure there must be a way to throw out all the completed lines (rather than just the first one). The solution doesn't have to use Scanner, it should just behave as intended.
The Scanner uses a buffer. It’s default size is 1024 characters. So by the first nextLine() call, it reads up to 1024 of the available characters into the buffer. This is necessary, as the Scanner doesn’t even know how many characters belong to the next line, before filling the buffer and searching for a line break in the buffer.
Therefore, if there are less pending characters than the buffer size, the loop will iterate only once. But even when there are more characters, and more loop iterations, the resulting state likely is to have some pending lines in the buffer.
As long as the Scanner’s buffer is in its initial empty state, you can flush the source stream directly, instead of using the scanner:
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
while(System.in.available() > 0) {
System.in.read(new byte[System.in.available()]);
}
System.out.println("What is your name?");
String name = scanner.nextLine();
System.out.println("Hi, " + name);
Note that it would be natural to use System.in.skip(System.in.available()); instead of read, but while trying it, I encountered a bug that the underlying stream did not update the available() count after a skip when reading from a console.
Note that if the Scanner is not in its initial state but has some buffered content already, there is no way to flush the buffer, as its API is intended to make no distinction between buffered and not yet buffered, so any attempt to match all content would result in reading from the source (and blocking) again. The simplest solution to get rid of the buffered content would be
scanner = new Scanner(System.in);

Why Exception log changes printed place with same code? [duplicate]

This question already has answers here:
System.out.println and System.err.println out of order
(7 answers)
Closed 9 years ago.
Please consider this java code:
public class CMain {
public static void main(String[] args){
for (int i = 0; i < 10; i++) {
System.out.println("A");
System.err.println("B");
}
}
}
By a quick look at the code, some of us may think the output has to be the print of As and Bs alternatively. However is not! It is a random appearance of 10 A characters and 10 B ones. Something like this:
Why is that? and what is the solution for it so that the As and Bs gets displayed alternatively ( A B A B A B ...)
Before I ask this question, I checked several other similar questions for solution and non worked for my case! I have brought some of them here:
Synchronization and System.out.println
Java: synchronizing standard out and standard error
Java: System.out.println and System.err.println out of order
PS. I am using Eclipse as my IDE
Why does this happen?
This is because out and err are two different output streams. However, both of them print on console. So you do not see them as different streams. Moreover, when you do out.println(), it is not guaranteed that you will see the output on the console as soon as the statement gets executed. Instead, the strings are usually(depends on the system) stored in an output buffer (if you will) which is processed later by the system to put the output from the buffer onto the screen.
Solution :(
Although, as Eng.Fouad pointed out that you can use setOut(System.err) or setErr(System.out) to make them ordered, I would still not suggest doing that when you are actually putting this in an application (only use it for debugging purposes).
What the proposed solution does is that it will end up using only one stream for both the standard output and the standard error, which I do not think is a good thing to do.
They are different OutputStreams. If you really need to guarantee the order of printing them, use:
System.setErr(System.out);
or
System.setOut(System.err);
Since there are two separate streams, the output you are giving is possible.

I can't see why my scanner in java is throwing a "NoSuchElementException"

We need to make something of a lexical analyzer, and I have had some trouble with a particular function of mine, useLoad, or more accurately, what happens in Main after useLoad is used.
I figured out that that was because...for some reason, buffer=keyboard.nextLine() is throwing the error, because it's not getting more input from the keyboard for some reason. I thought that .nextLine() should force it to get more input from the user. And I don't know why it's throwing that exception specifically after this one particular method. It can do other methods just fine and not lose its ability to read. Is it because I have a variable called keyboard in another object and closed it? That seems doubtful. Just tried changing the name. Didn't make a difference.
Variables used but not declared in the below code: Keywords[0] is the String "load ". initial = the scanner string that's passed in to the function. offset = a counter variable, to see how far in to the line we've read.
The useLoad function (which is what I think is messing up somehow), is at the bottom, but I included everything it runs through (with each method separated by a horizontal rule), in chronological order, just in case I'm just not seeing what's going on.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in); //the scanner for keyboard
int i = 0;
String buffer ="";
boolean loopControl == true;
SymbolTable mySym = new SymbolTable();
System.out.println("READY FOR INPUT\n");
while (loopControl == true){
//read in the line
buffer = "";
buffer = keyboard.nextLine();
if(!mySym.checkStop(buffer)){ //if we didn't stop
mySym.primary(buffer);
}
else{//if we did stop
closeLoop();
}
if (i >= 55){
loopControl = false;
System.out.println(("You have gone over the limit ("+i+" lines) per execution. Please continue by running this program again.").toUpperCase());
//just a safety precaution...you know... in case closeLoop doesn't work
}
i++;
}
keyboard.close();
}
if(initial.substring(0, Keywords[0].length()).equals(Keywords[0])){ //Load
//if this is working as expected, then we simply need to do what the keyword says to do.
offset += Keywords[0].length(); //we have moved this much deeper in to the line
useLoad(offset, initial);
offset = 0; //just make sure, once we are done with the line, we start back at the start of the next line.
return; //we found what we were looking for, get out.
}
private void useLoad(int offsetIn, String readIn) {
double doubIn = 0;
//now get the value of the
Scanner keyboard = new Scanner(System.in); //the scanner for keyboard
System.out.println("\nENTER VALUE FOR " + readIn.toUpperCase());
doubIn = keyboard.nextDouble();
keyboard.close();
variables.create(readIn.substring(offsetIn), doubIn);
}
I think I've figured out your problem.
Java docs for both Java 7 and 8 include this line in Scanner's close method documentation:
If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked.
Looking into the docs for System, I've found that System.in is of type InputStream which, you guessed it, implements Closeable. The close method documentation for InputStream says that it does nothing; however, InputStream is abstract and close is not marked as final, which means it can be overridden. System.in returns an InputStream which could potentially - and clearly does - do something.
So the problem is, you are creating multiple Scanners with System.in, and each time you close any one of them, you close System.in, rendering it useless!
This problem has actually been discussed in another question here, with a solution given. That said, for your program I would suggest one of two approaches:
The first approach is mentioned there: Either use a pre-made wrapper class or make your own, which accepts an InputStream in its constructor. Have this class' InputStream implementation call all the methods of its wrapped object, except for the close method which is a no-sell, and then pass Wrapper(System.in) to Scanner instead of System.in directly. However, I would be wary of taking this approach except in very specific circumstances, because any time you use one of these wrappers you would need to remember to close its wrapped object at the end of its use, unless it's something like System.in.
Second approach: Use a runner class in your program, and initialize the scanner there. Pass the scanner into the required objects during construction for them to hold a reference to, and then allow them to complete their required tasks without closing Scanner within the class. Once the exit condition is specified, return to the runner class and close Scanner from there.
You close the keyboard each time round the loop. Therefore the second time around you read from a closed keyboard object.
A quick look at the documentation for Scanner.nextLine contains the news that it might throw:
NoSuchElementException - if no line was found

Java program to display character instantly [duplicate]

This question already has answers here:
How to read a single char from the console in Java (as the user types it)?
(7 answers)
Closed 7 years ago.
I want to write a program which instantly displays a character when it is typed in console. For example, output asks 'Enter'. Suppose I write char 'g' in console. It should instantly display in console. Also, after entering char, I don't want to press enter. Please explain to me how can I achieve this and also explain the concept.
I have tried this code:
import java.io.*;
public class input {
public static void main(String[] args) throws IOException {
InputStreamReader ir=new InputStreamReader(System.in);
System.out.println(ir.read());
}
}
Depending on the development environment, System.console() may return null. Personally, I'm not sure what's the safest way to go about instantiating some kind of "mock" console in this case.
Although, you can create the illusion of this by using a native key listener like JNativeHook, which listens for key strokes without a GUI. Once a key is a pressed, you can print to the console using System.out.print. This also ensures that when they user types a key, it's not entered twice (once for the user to enter it, and another time for displaying it). Technically, the console already displays letters as soon as the user types it ;)
String randomWords;
Scanner kb = new Scanner(System.in);
System.out.print("Please enter words: ");
randomWords = kb.nextLine();
System.out.println(randomWords);
If you want to continuously get and print text then put the last two lines in a loop.

Redirect lots of system.out.println's to a .txt file [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Print java output to a file
In a Java program, I have a long method, (which I don't think is important to post since it's not vital to the question) that has a large number of println statements to print status updates to the console.
Instead of having these printout to the console, I'd like them to go into a txt file where I can store them and review them later.
Is there a simple way to redirect the output without manually going through each println statement?
If not, what's the best way to go about this?
I have had to do this before, it isn't very neat and I hope you aren't doing it for a final piece of code, but I did:
PrintStream ps = new PrintStream("\file.txt");
PrintStream orig = System.out;
System.setOut(ps);
//TODO: stuff with System.out.println("some output");
System.setOut(orig);
ps.close();
The System class has a static method, System.setOut(PrintStream out). All you have to do is create your own PrintStream that writes to a file, stuff it into this method and you're all set.
Better less fragile solution: Don't use System.out.printFoo(...) but instead just use a logger, and change the logging levels as it suits your purposes at that time.
add extra parameter to the method , PrintStream out
search&replace System.out with out in your method.
done.
(call method with a PrintStream wrapped around a FileOutputStream)

Categories