Closing BufferedReader and InputStreamReader - java

This piece of code is creating memory leak issues cause of BufferedReader and InputStreamReader which I think might be happening cause of some exceptions. How should I change it?
try{
URL url = new URL(sMyUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
while ((str = in.readLine()) != null) {
jsonString += str;
}
in.close();
}catch(Exception e){
}

It would be safer to close your stream using a try..finally block. You might also use a StringBuilder as it is designed for concatenating strings. You should also avoid catching Exception and doing nothing with it. Also, your code is concatenating lines without any line-breaks. This may well not be what you want, in which case append("\n") when you read each line in.
Here's a version with those modifications:
StringBuilder json = new StringBuilder();
try {
URL url = new URL(sMyUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
try {
String str;
while ((str = in.readLine()) != null) {
json.append(str).append("\n");
}
} finally {
in.close();
}
} catch (Exception e) {
throw new RuntimeException("Failed to read JSON from stream", e);
}

The code isn't pretty but won't be creating a memory leak. I suggest you use a memory profiler to determine where your memory is being used. Otherwise you are just guessing even if you have ten + years experience performance tuning in Java ;)
A better alternative is to use Java 7
URL url = new URL(sMyUrl);
try(BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) {
while ((str = in.readLine()) != null) {
jsonString.append(str).append("\n");
}
}
If you have Java 6 or older you can use.
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) {
try {
while ((str = in.readLine()) != null) {
jsonString.append(str).append("\n");
}
} finally {
in.close();
}

Related

Getting data from php file in my Android java class using bufferreader

I am getting data from php file in android java class using
BufferedReader reader = new BufferedReader(new
InputStreamReader(con.getInputStream()));.
This code is in my php file is
echo "abc";
echo "xyz";
This is the code of my java file.
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = null;
Complete_line = null;// Read Server Response
while ((line = reader.readLine()) != null) {
System.out.println(line);
break;
}
But when I read from Buffer reader it will read a whole one line, or it will print "line" string as "abcxyz". But I want them as two lines as they are two different lines in the PHP file.
try this,
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line+"\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In PHP, unless you seperate the 2 lines a a newline character \n, the two echos are the same. To seperate echos into different lines, you need to end the strings with \n, like this:
echo "abc\n";
echo "xyz\n";

How to read wsdl from a url using java

I'm new to java. I want to read wsdl from java. I have sample northwind service http://services.odata.org/Northwind/Northwind.svc/$metadata
I want to read output xml for the above URL. I tried in different ways, It didn't work.
URL oracle = new URL("http://services.odata.org/Northwind/Northwind.svc/$metadata");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
Method #2
private static void readHttp() {
Charset charset = Charset.forName("US-ASCII");
Path file = Paths.get("http://services.odata.org/Northwind/Northwind.svc/$metadata");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
}
Can anyone suggest me how to proceed on this.
Thanks,
Use org.apache.commons.io.IOUtils
IOUtils.toString(new URL("http://services.odata.org/Northwind/Northwind.svc/"));

Android strange bug while downloading a JSON

I need to download a JSON in a string, i'm almost sure the code isn't wrong, but there's something strange...
public boolean downloadJSON(){
json="";
try{
URL url = new URL(theURL);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
json+=line;
}
in.close();
return true;
} catch (Exception e) {
return false;
}
}
Basically it open the buffer correctly, it read the json correctly and store it in the variable, it close the stream, then it go to the return true and... It randomly jump to the return false without sense, and while it's on the return false the Exception e is... null O.o
That make absolutely no sense, help me please D:!!!
In the end i solved it in this way:
public boolean downloadJSON(){
json="";
boolean out=false;
try{
URL url = new URL(theURL);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
json+=line;
}
in.close();
out = true;
} catch (Exception e) {
}
return out;
}
Don't ask me how this is supposed to be correct if the first doesen't work, in my mind i still think the first should work :S
ADD: for Stephen C:
public boolean downloadJSON(){
json="";
try{
URL url = new URL("http://fapfapfap.altervista.org/conapo/conapo.php?n="+numeroPagina);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null){json+=line;}
in.close();
return true;
}catch (Exception e) {
Log.d("ERRORE", e.getStackTrace().toString());
return false;
}
}
Try this:
URL url = new URL(theURL);
StringBuilder jsonResults = new StringBuilder();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
System.out.println(jsonResults.toString());
.... it still make no sense that my code jumped to the false without exception
You are misinterpreting the evidence:
public boolean downloadJSON(){
json = "";
try {
URL url = new URL(theURL);
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
json += line;
}
in.close();
return true;
} catch (Exception e) {
return false; // HERE
}
}
When you get to the statement I've labelled // HERE. It has happened >>because<< some exception has been thrown. There is absolutely no doubt about it. We don't know what exception it was, because your code simply throws away the exception object.
(Try adding e.printStacktace(); before the return false;)
I suspect it is either going to be a MalformedURLException, on a FileNotFoundException ... but it could be other things.
So what are your mistakes in this code?
1) Catching Exception is bad idea. The problem is that it catches too much. In addition to catching the exceptions that you (might have) expected at this point, it will catch all of the unexpected ones as well. For example, any NPEs or AIOOPEs or whatever arising from (hypothetical) bugs in your code.
In this case, you should probably catch the exceptions that are likely at this point; i.e. IOException.
2) Catching an exception and throwing away the stacktrace makes it hard to diagnose a problem. It is only advisable to "squash" an exception like that if you know (and can prove) that the exception is going to be what you expect.
3) Doing both 1) and 2) in the same piece of code is a REALLY bad idea.
4) Building a string like that is inefficient (or very inefficient ... if you are loading a really large document). Using a StringBuilder is much better.
Note however the 4) is peripheral to the problem you were having.

Initialization in while block?

Isn't there a cleaner way of doing the following (eliminating the need for initializing line prior to the while block)? It just seems unnecessary to intialize a variable prior to its usage instead of doing something like while ((String line = br.readLine) != null) {}. If not, why not?
BufferedReader reader = null;
try
{
File file = new File("sample-file.dat");
reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
No, you cannot avoid initializing the variable. However, you can use Try-With-Resources to make it a lot cleaner.
try (BufferedReader reader = new BufferedReader(new FileReader("sample-file.dat"))) {
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
Just adding this for completions sake, if anyone is using Java 8, you have access to the Stream API. Using this you can just simply do the following:
BufferedReader reader = new BufferedReader(...);
reader.lines().forEach(System.out::println);
And if you're wondering, the code under the hood that produces this does check for null lines.
No you can't declare (and use) a variable in the while loop expression evaluation step. But, you can eliminate the finally block by using a try-with-resources
try (
File file = new File("sample-file.dat");
BufferedReader reader = new BufferedReader(new FileReader(file));
) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
No, you can't declare a variable inside the condition definition except in a for loop. Can't really say why - perhaps because the condition is not supposed to be somewhere you initialize things, whereas a for initialization step is.
But anyway, especially in cases where the loop conditions are complicated, some coders prefer to use
while (true) {
String line = reader.readLine();
if ( line == null )
break;
System.out.println(line);
}
But it's really a matter of style.

Java Process can't get ErrorStream message

everyone, I have a process that needs to get standard output and log/error/exception output from the subprocess. The standard output is fine, but I can't get ErrorStream, therefore the program is stuck there because of that. Here is my simple code. There is nothing magic, but why can't I get the error stream here? Thanks for looking at it.
BufferedReader standard =
new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader error =
new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = standard.readLine()) != null) {
System.out.println(line);
}
while ((line = error.readLine()) != null) {
System.out.println(line);
}
Now, as suggested, i used two threads to process the output and error streams, but still had the same problem, as follows. Can anybody give me some insights? Thanks.
ProcessBuilder pb = new ProcessBuilder(listArgs);
pb.redirectErrorStream();
Process process = pb.start();
StreamThread output = new StreamThread(process.getInputStream());
StreamThread error = new StreamThread(process.getErrorStream());
output.start();
error.start();
while (true) {
try {
output.join();
break;
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
The definition of the StreamThread:
public static class StreamThread extends Thread{
private InputStream input = null;
public StreamThread(InputStream in){
input = in;
}
String line = null;
public void start(){
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
try{
while( (line=reader.readLine()) != null ){
System.out.println(line);
}
reader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
Look at your loops:
while ((line = standard.readLine()) != null) {
System.out.println(line);
}
while ((line = error.readLine()) != null) {
System.out.println(line);
}
You're going to keep reading from the output stream until it's finished - which is likely to be when the process terminates. Only then do you start reading the error stream.
You should probably put at least one of these into a different thread, so you can read from both streams at the same time.

Categories