BufferedReader java.io.IOException: stream is closed - java

I'm calling a BufferedReader to get a HTTP response body (if it exists) and stick it in one long string variable. Sometimes when I attempt to do this I get the error java.io.IOException: stream is closed sometimes when the while loop below starts to execute. I don't understand why. I'd like to make sure the object isn't null and that is has a response body before reading in the object.
BufferedReader readBuffer = null;
if (connection.getResponseCode() >= 200 && connection.getResponseCode() <= 299) {
readBuffer = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
readBuffer = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
if(readBuffer != null) {
// Get the response body output from the server
StringBuilder calculatedOutput = new StringBuilder();
String rawOutputLine;
while ((rawOutputLine = readBuffer.readLine()) != null) {
calculatedOutput.append(rawOutputLine);
}
Logger.debug(String.format("BODY: %s", calculatedOutput.toString()));
readBuffer.close();

Try this to read the response:
BufferedReader readBuffer = null;
try {
if (connection.getResponseCode() >= 200 && connection.getResponseCode() <= 299) {
readBuffer = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
readBuffer = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
// Get the response body output from the server
StringBuilder calculatedOutput = new StringBuilder();
String rawOutputLine;
while ((rawOutputLine = readBuffer.readLine()) != null) {
calculatedOutput.append(rawOutputLine);
}
Logger.debug(String.format("BODY: %s", calculatedOutput.toString()));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
readBuffer.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Try this code:
BufferedReader readBuffer = null;
if (connection.getResponseCode() >= 200 && connection.getResponseCode() <= 299) {
readBuffer = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
readBuffer = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
if(readBuffer != null) {
// Get the response body output from the server
StringBuilder calculatedOutput = new StringBuilder();
String rawOutputLine;
if(readBuffer.ready()) {
while ((rawOutputLine = readBuffer.readLine()) != null) {
calculatedOutput.append(rawOutputLine);
}
}
Logger.debug(String.format("BODY: %s", calculatedOutput.toString()));
readBuffer.close();

Related

Reading multiple lines from server

I'm open for other ways to do this, but this is my code:
public class Client {
public static void main (String [] args) {
try(Socket socket = new Socket("localhost", 7789)) {
BufferedReader incoming = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter outgoing = new PrintWriter(socket.getOutputStream(),true);
StringBuilder sb = new StringBuilder();
Scanner scanner = new Scanner(System.in);
String send = "";
String response = "";
while (!send.equals("logout")){
System.out.println("Enter Command: ");
send = scanner.nextLine();
outgoing.println(send);
while ((response = incoming.readLine()) != null) {
System.out.println(response);
sb.append(response);
sb.append('\n');
}
}
} catch (IOException e) {
System.out.println("Client Error: "+ e.getMessage());
}
}
}
I do get response from the server, but the program is getting stuck in the inner while loop while ((response = incoming.readLine()) != null), so i can't enter a second command. how do i break the loop if the incoming response is done ?
The problem is that incoming.readLine() will only return null if the socket is closed, otherwise it will block and wait for more input from the server.
If you can change the server, you could add some marking that the request was fully processed and then check it like this while ((response = incoming.readLine()) != "--finished--").
If you cannot, try this:
while(response.isEmpty()){
if(incoming.ready()){ //check if there is stuff to read
while ((response = incoming.readLine()) != null){
System.out.println(response);
sb.append(response);
sb.append('\n');
}
}
}

bufferedReader.readLine does not work within IF in Android

I am writing Android. The app should read line of a file from web, and shows the message on the textView. I use bufferedReader. It works fine when I have bufferedReader.readLine() inside a while loop. But it does not work when I have it in a IF statement (shows nothing, although there's something I see in debug mode).
#Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
String result = "";
try {
URL url = new URL("http://www.tc.umn.edu/~yang4131/jtest.json");
urlConnection = (HttpURLConnection) url.openConnection();
int code = urlConnection.getResponseCode();
if(code==HttpURLConnection.HTTP_OK){ // 200
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
if (in != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String line = "";
/*
if((line = bufferedReader.readLine()) != null)
result += line;
if((line = bufferedReader.readLine()) != null)
result += line;
if((line = bufferedReader.readLine()) != null)
result += line;
*/
while ((line = bufferedReader.readLine()) != null)
result += line;
}
in.close();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
urlConnection.disconnect();
}
return result; // this return statement is needed, no matter what
}
I replicated this thing in pure Java in Eclipse, with a local file. It works fine. I really have no idea.
Solved.
Adding result += "\n\n\n\n"; after the concatenation will make the content appear. I think this has something to do with UI, perhaps my textView is blocked for few lines or whatnot.

File can not read correctly

I trying to read a json file from dbpedia and parse it. But the code that i have wrote can not correctly read the whole json file and for that reason parsing error comes. Here is my code for reading and parsing...
URL url=new URL("http://dbpedia.org/data3/assembly.json");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String inputLine="asdf";
while (( in.readLine()) != null)
{
if (inputLine=="asdf")
inputLine=in.readLine();
else
inputLine+=in.readLine();
//System.out.println(inputLine);
}
System.out.println(inputLine);
Object obj = parser.parse(inputLine);
JSONObject jsonObject = (JSONObject) obj;
You can create a helper method to read the file from url:
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1) {
buffer.append(chars, 0, read);
}
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
then you can call the method like this
try {
JSONObject json = new JSONObject(readUrl("http://dbpedia.org/data3/assembly.json"));
...
} catch (JSONException e) {
e.printStackTrace();
}
It's up to you, if you need StringBuffer or StringBuilder

How to read first five character from buffered reader?

I have this code
Process p =Runtime.getRuntime().exec("busybox");
InputStream a = p.getInputStream();
InputStreamReader read = new InputStreamReader(a);
BufferedReader in = new BufferedReader(read);
Running it from the terminal the first lines of oupout return the version of Busybox. If I wanted to take for example the first 5 characters as I do?
While the other answers should work well too, the following will exit and close the stream after reading five characters:
Process p = Runtime.getRuntime().exec("busybox");
InputStream a = p.getInputStream();
InputStreamReader read = new InputStreamReader(a);
StringBuilder firstFiveChars = new StringBuilder();
int ch = read.read();
while (ch != -1 && firstFiveChars.length() < 5) {
firstFiveChars.append((char)ch);
ch = read.read();
}
read.close();
a.close();
System.out.println(firstFiveChars);
try
String line = in.readLine();
if(line!=null && line.length() >5)
line = line.substring(0, 5);
Do this way
Process p;
try {
p = Runtime.getRuntime().exec("busybox");
InputStream a = p.getInputStream();
InputStreamReader read = new InputStreamReader(a);
BufferedReader in = new BufferedReader(read);
StringBuilder buffer = new StringBuilder();
String line = null;
try {
while ((line = in.readLine()) != null) {
buffer.append(line);
}
} finally {
read.close();
in.close();
}
String result = buffer.toString().substring(0, 15);
System.out.println("Result : " + result);
} catch (Exception e) {
e.printStackTrace();
}
Output
Result : BusyBox v1.13.3

Reading data from an API

I have written a function to read some data from an external API. What my function does is , it calls that API while reading a file from the disk. I want to optimize my code for large size of a file (35000 records). Could you please suggest me on this.
Following is my code.
public void readCSVFile() {
try {
br = new BufferedReader(new FileReader(getFileName()));
while ((line = br.readLine()) != null) {
String[] splitLine = line.split(cvsSplitBy);
String campaign = splitLine[0];
String adGroup = splitLine[1];
String url = splitLine[2];
long searchCount = getSearchCount(url);
StringBuilder sb = new StringBuilder();
sb.append(campaign + ",");
sb.append(adGroup + ",");
sb.append(searchCount + ",");
writeToFile(sb, getNewFileName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private long getSearchCount(String url) {
long recordCount = 0;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(
"api.com/querysearch?q="
+ url);
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(response.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null) {
try {
JSONObject json = (JSONObject) new JSONParser()
.parse(output);
JSONObject result = (JSONObject) json.get("result");
recordCount = (long) result.get("count");
System.out.println(url + "=" + recordCount);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
httpClient.getConnectionManager().shutdown();
} catch (Exception e) {
e.getStackTrace();
}
return recordCount;
}
Since remote calls are slower than local disk access, you'll want to in some way parallelize or batch your remote calls. If you can't make batch calls to the remote API, but it allows multiple concurrent reads, then perhaps you want to use something like a thread pool to make the remote calls:
public void readCSVFile() {
// exception handling ignored for space
br = new BufferedReader(new FileReader(getFileName()));
List<Future<String>> futures = new ArrayList<Future<String>>();
ExecutorService pool = Executors.newFixedThreadPool(5);
while ((line = br.readLine()) != null) {
final String[] splitLine = line.split(cvsSplitBy);
futures.add(pool.submit(new Callable<String> {
public String call() {
long searchCount = getSearchCount(splitLine[2]);
return new StringBuilder()
.append(splitLine[0]+ ",")
.append(splitLine[1]+ ",")
.append(searchCount + ",")
.toString();
}
}));
}
for (Future<String> fs: futures) {
writeToFile(fs.get(), getNewFileName());
}
pool.shutdown();
}
Ideally, though, you'd really want to make a single batch read from the remote API if at all possible.

Categories

Resources