This question already has answers here:
Using BufferedReader.readLine() in a while loop properly
(7 answers)
Closed 8 years ago.
I have problem with reading from my socket i read only if value isn't null but it doesnt't works.
#Override
public void run() {
System.out.println("Reading from socket");
while(true){
try {
if(!(br.readLine().equals(null)))read += br.readLine();
} catch (IOException e) {
System.out.println("error " + e);
}
}
}
here is error:
Exception in thread "Thread-4" java.lang.NullPointerException
at connection.CreateConnection.run(CreateConnection.java:61)
at java.lang.Thread.run(Unknown Source)
If br.readLine() returns null, then calling .equals(null) on it will throw an exception - it won't return true. You just want to compare reference identity with null.
Calling .equals(null) is never useful, unless you're testing that your equals implementation works properly :)
Additionally, you'll be skipping every other line by calling readLine() twice on each loop iteration.
You want something like:
String line;
if ((line = br.readLine()) != null) {
read += line;
}
... except that will be painfully slow due to repeated string concatenation. You should almost certainly be using a StringBuilder instead.
Also, doing all of this in a loop which catches IOException seems like a recipe for disaster - if the a call fails, it's very likely that it'll keep failing forever, whereupon your program is basically hung in a tight loop. You should almost certainly stop when you get an exception, rather than keeping going. For example:
try {
String line;
while ((line = reader.readLine()) != null) {
read += line; // Or builder.append(line);
}
} catch (IOException e) {
// Whatever you want to do
}
Finally, consider the value of whitespace, both horizontal and vertical, as well as the benefits of using braces even in single-statement if statements etc. The line if(!(br.readLine().equals(null)))read += br.readLine(); is compact at the expense of readability.
Say you are on the last line of your file, you call br.readLine() to check if it's not null. Your line exists so your test passes. Then you call br.readLine() once again. Unfortunately there is nothing left to read! And you get your exception.
Rewrite your code like that:
#Override
public void run() {
System.out.println("Reading from socket");
String line;
while(true){
try {
line = br.readLine()
if((line != null))read += line;
} catch (IOException e) {
System.out.println("error " + e);
}
}
}
You are calling .equals() on a null object, which causes the null pointer issue I assume. If you want to read with a buffered reader, try doing something like:
String line = reader.readLine();
while(line != null){
System.out.println(line);
line = reader.readLine();
}
This will eliminate the issue of null pointers, and will also stop you from skipping any lines during reading.
Related
To run the terminal from my intelliJ I wrote next code:
public static String runTerminalCommand (String command){
Process proc = null;
try {
proc = Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
// Read the output
BufferedReader reader =
new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
try {
while((line = reader.readLine()) != null) {
out.print(line + "\n");
return line;
}
} catch (IOException e) {
e.printStackTrace();
}
try {
proc.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
If there is a way to simplify this :)
I would first look into correctness here; that one line:
return line;
looks suspicious. Or, more precisely: are you sure that your command will always print exactly one line? Because you are returning after reading the first line; and thus omitting any other output.
Besides: you should change your code to use try-with resources instead - your return statement just leaves your readers unclosed. Probably not a problem here because all of that should go away when the process object goes away, but still: bad practice. "Cleanup things" before exiting your methods!
To answer the actual question: after looking into these conceptual things I am pointing out, there isn't much else you could do. Probably use a ProcessBuilder instead of the somehow "outdated" Runtime.exec() call.
I'm currently working on a simple method which converts the content of a file to a string. I saw several topics covering some detail about this question (here). However I can use the try catch or a return do_nothing as mentioned in the previous linked answer. The code:
public static String getStringFromFile(String path) throws EmptyFileException {
String data =null;
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while ((line = reader.readLine()) != null) {
data += line +"\n";
}
if (data == null) {
throw new EmptyFileException();
}
}
catch (FileNotFoundException ex) {
showExceptionMessage("File not found");
}
catch (IOException ex) {
showExceptionMessage("Can't read the file");
}
return(data);
}
private static void showExceptionMessage(String message) {
JOptionPane.showMessageDialog(null, message, "ERROR", JOptionPane.ERROR_MESSAGE);
}
So what would be "better" throwing an exception if the file is empty or just using return doNothing() (were doNothing is the function that does nothing, makes sense right? hahah).
Is this a good way to avoid null return?
Yes, always return "existing" object instead of null if you can. Null Object Pattern is a good aproach to avoid that.
So what would be "better" throwing an exception if the file is empty
or just using return doNothing()
In your case throwing an exception is overkill for me. You should throw an exception when you don't expect particular behaviour. Have a look at FileNotFoundException. You always expect that file exists so it's a good choice to throw exception when you can't find this file.
So as metioned above null is bad, so why can't you return empty string? :) In this case it will work like Null Object Pattern, like placeholder :)
My Android code is behaving funny. The input stream should and does throw an IOException, which correctly causes control to go to // read an error stream. The error stream is read correctly and the debugger steps to return error_message with the error_message variable containing expected characters read from error stream. It then correctly steps to the // no op in the finally block, which I added just for kicks.
And then, it steps to return "all hope lost";!! Which then, instead of returning to the caller, steps into some Android system code that throws a SecurityException with a message about lack of content permissions.
Removing the finally block has no impact -- the bug still happens. The streams being read are from an HTTP URL Connection. No problems if server returns 200 but if server returns 400 it goes through the weird path described above and tries to throw the weird SecurityException.
try {
// read an input stream into message
return message;
} catch (IOException outer) {
try {
// read an error stream into error_message
return error_message;
} catch (IOException inner) {
return "all hope lost";
}
} finally {
// no op, just to step debugger
}
Update: Posting exact code and debug trace.
try {
/*x*/ BufferedReader buffered_reader =
new BufferedReader(
new InputStreamReader(
new BufferedInputStream(http_url_connection.getInputStream())));
StringBuilder string_builder = new StringBuilder();
String line;
for (line = buffered_reader.readLine();
line != null;
line = buffered_reader.readLine()) {
string_builder.append(line);
}
return string_builder.toString();
} catch (IOException io_exception) {
this.io_exception = io_exception;
BufferedReader buffered_reader =
new BufferedReader(
new InputStreamReader(
new BufferedInputStream(http_url_connection.getErrorStream())));
StringBuilder string_builder = new StringBuilder();
try {
for (String line = buffered_reader.readLine();
line != null;
line = buffered_reader.readLine()) {
string_builder.append(line);
}
/*y*/ String error_message = "server error: " + string_builder.toString();
return error_message;
} catch (IOException exception) {
String level_2_error_message = "level 2 error: " + exception.getMessage();
return level_2_error_message;
} finally {
return "foo";
}
}
Line /*x*/ causes the jump to the first catch as expected. All lines up to /*y*/ are then executed as expected. Then the weird thing is that line /*y*/ does not complete and control immediately goes to either the next catch block if there is no finally or to the finally. If there is a finally then it does not to got the last catch block.
The contents of the string buffer on /*y*/ line look perfectly fine -- a 20 character string from the server.
You say that an exception is being thrown by line /* y */
By my reading of that line of code, the following are plausible explanations:
The exception is a NullPointerException because string_builder is null. But it can't be.
The exception is an OutOfMemoryError because you don't have enough free space for the toString() call to create the new String object.
It is possible that StringBuilder is not java.lang.StringBuilder but some class you wrote yourself. In that case, any exception is possible.
However, I can't see how you would end up in the second IOException handler.
Apart from that, the only other likely explanation is that that source code does not match the code that you are actually executing; e.g. you forgot to recompile something, or you forgot to redeploy after your last compilation.
For what it is worth, your return in your finally is almost certainly a mistake.
It means that you will return "foo" instead of either of the error messages.
If (for example) string_builder.toString() did throw an NPE or OOME, then the return would squash it.
A finally with a return can have non-intuitive behaviour. It is certainly NOT something you should do "for debugging"!!!
I need to read a text file line by line till I find a specific string. I'm using BufferedReader.readLine() but when I debug I find that it starts from the third line in the file and skips lines after that.
Here is my code:
try {
reader = new BufferedReader(new FileReader(path));
String line1 = null;
while ((line1 = reader.readLine()) != null) {
if (line1.toString() == invocation0) {
found = true;
return false;
} else if (line1 == invocation1) {
found = true;
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
}
}
I would really appreciate any help, as I tried many different solutions for this and still can't solve this issue.
the content of the file is like:
.//============================================================================
.// File: abc.mark
.// Description: anything
.// Notice: anything
.// .//============================================================================
.invoke RemoveClass("Properties",0)
if(line1.equals(invocation0))
Use equals() method for String value comparison.
Also, instead of return within the if, you can use a break. This is just a suggestion though.
BufferedReader should not be skipping the anything. Unfortunately you are the one who is making read method to skip the line. The equlaity operator == will not compare the content of any two strings, rather it compares whether they are of same object. You could possibly avoid it in two ways.
Call the intern() on invocation0 (line1 object should have been interned before anyway)
More precisely use equals method line1.equals(invocaton0)
This link may be of some help for you to understand it better.
I'm writing a file reader that returns an object and I'd like it to warn on parse errors and continue to the next record.
The code below is the obvious implementation of this, but involves recursing from inside the catch block. Is there any technical or stylistic reason not to do this?
public RecordType nextRecord() throws IOException{
if (reader == null){
throw new IllegalStateException("Reader closed.");
}
String line = reader.readLine();
if (line == null){
return null;
}else{
try {
return parseRecord(line);
}catch (ParseException pex){
logger.warn("Record ignored due to parse error: "
+ pex.getMessage());
//Note the recursion here
return nextRecord();
}
}
}
I would prefer to use a loop. With recursion, you never know how deep you can safely go.
String line;
while((line = reader.readLine()) != null) {
try {
return parseRecord(line);
}catch (ParseException pex){
logger.warn("Record ignored due to parse error: " + pex);
}
}
return null;
Why not replace the recursion with a loop:
public RecordType nextRecord() throws IOException {
if (reader == null) {
throw new IllegalStateException("Reader closed.");
}
for (;;) {
String line = reader.readLine();
if (line == null) {
return null;
} else {
try {
return parseRecord(line);
} catch (ParseException pex) {
logger.warn("Record ignored due to parse error: "
+ pex.getMessage());
// continue to the next record
}
}
}
}
Stylistically, I find this preferable.
Would it be cleaner to let the ParseException propagate back to the caller? The caller could then decide what to do about it.
What it seems like to me is that whatever is calling your method is going to keep calling it until the method returns null.
I would probably follow the advice of the previous posters and use a loop, however I would look at whatever is calling the method (as it is probably already using a loop), have it skip the line by looking for an exception to be thrown.