I'm reading a URL with the following code:
URL myURL = new URL("htpp://path_to_my_file");
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(myURL.openStream()));
while (reader.ready()) {
String line = reader.readLine();
...
}
} catch (IOException e) {
throw new RuntimeException("Parsing of file failed: " + myURL, e);
}
Could it happen, that the file is not read completely? (because of network problems or something else?). If yes, is there a way to test it or even to avoid?
The background: I'm working on an application (not written by me up to this point) and users report me that parts of files are missing sometimes. It happens sporadically so my only guess was that something sometimes fails when the file is read in but I have too few java-background to be sure...
Yes, you'll know it's happened when you get an IOException as per the Reader.readLine docs.
So you'll want to catch the Exception, something like this:
try {
while (reader.ready()) {
String line = reader.readLine();
}
}
catch(IOException e) {
// Bah! Humbug!
// Should really log this too. So if you're using Log4j:
log.error("Error reading from URL " + myURL.toString(), e);
} finally {
try { if (reader != null) reader.close(); }catch(Exception e){}
}
Somewhere here, I found the following comment:
ready() != has more
ready() does not indicate that there is more data to be read. It only shows if a read will could block the thread. It is likely that it will return false before you read all data.
To find out if there is no more data check if readLine() returns null
It sounds that the implementation with reader.ready() causes my problem. Am I wrong with this assumption?
Related
firstly I know I should be using a try-catch with resources, however I don't currently have the most up to date JDK on my system.
I have the following code below, and am trying to ensure the resource reader is closed using the finally block, however the code below doesn't compile for two reasons. Firstly is that reader may have not been initialized and secondly that close() should be caught within its own try-catch. Dont both of these reasons defeat the object of the initial try-catch block?
I can solve the issue with the finally block close() statement by putting it in its own try-catch. However this still leaves the compile error about reader not being initialized?
I'm presuming I have gone wrong somewhere? Help appreciated!
Cheers,
public Path [] getPaths()
{
// Create and initialise ArrayList for paths to be stored in when read
// from file.
ArrayList<Path> pathList = new ArrayList();
BufferedReader reader;
try
{
// Create new buffered read to read lines from file
reader = Files.newBufferedReader(importPathFile);
String line = null;
int i = 0;
// for each line from the file, add to the array list
while((line = reader.readLine()) != null)
{
pathList.add(0, Paths.get(line));
i++;
}
}
catch(IOException e)
{
System.out.println("exception: " + e.getMessage());
}
finally
{
reader.close();
}
// Move contents from ArrayList into Path [] and return function.
Path pathArray [] = new Path[(pathList.size())];
for(int i = 0; i < pathList.size(); i++)
{
pathArray[i] = Paths.get(pathList.get(i).toString());
}
return pathArray;
}
There is no other way then initialize your buffer and catch the exception. The compiler is always right.
BufferedReader reader = null;
try {
// do stuff
} catch(IOException e) {
// handle
} finally {
if(reader != null) {
try {
reader.close();
} catch(IOException e1) {
// handle or forget about it
}
}
}
The method close will always need a try-catch-block since it declares that it could throw an IOException. It doesn't matter if the call is in a finally block or somewhere else. It just needs to be handled. It is a checked exception.
Read must also be initialized just by null. IMHO this is super useless, but that's Java. That is how it works.
Instead check if reader is null or not and then close it accordingly like below (you should call close() on reader only if it's not null or if it's been already instantiated else you will end up getting null reference exception).
finally
{
if(reader != null)
{
reader.close();
}
}
I am running another jar with this code:
(I am updating a gui in some parts , so dont feel confused.)I get an IO Exception (Stream Closed) here:
if((line = readr.readLine()) != null){
Thats the full code:
if(!data.serverStarted()){
try{
data.updateConsole("Starting server!");
String fileDir = data.dir + File.separator + "craftbukkit.jar";
Process proc = Runtime.getRuntime().exec("java -Xmx2048M -jar "+"craftbukkit.jar"+" -o true --nojline");
data.setOutputStream(proc.getOutputStream());
InputStream is = proc.getErrorStream();
}catch(IOException ex){
ex.printStackTrace();
}
BufferedReader readr = new BufferedReader(new InputStreamReader(is));
data.setServerStarted(true);
String line;
while(data.serverStarted()){
try {
if((line = readr.readLine()) != null){
data.updateConsole(line);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
readr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}else{
data.updateConsole("You have already started your server!");
}
You have a while loop that closes readr on every pass. The next time it gets to the try block, readr is closed. Perhaps you intended to put the try/catch block around the while loop?
You are closing the reader inside the loop that reads from it. You need to close it outside of the loop:
try {
String line;
while (data.serverStarted() && ((line = readr.readLine()) != null)) {
try {
data.updateConsole(line);
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
try {
readr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I am surprised that this code even compiles.
You declare the actual InputStream is inside the try/catch at the beginning, but that makes it only visible inside that block. So whatever you give to the BufferedReader a few lines below is something else and most likely not what you think it is.
In addition your while(data.serverStarted()) does not check if the stream is still open, and later you only use a single if check (again with no check if the stream is open), so you'll only read one single line at best.
I have a feeling that you had a bad OutOfCoffeeException while writing this code. ;)
I request a text file from a server. The url does not end in some_file.txt, because the file is created dynamically per the request (not sure if that is even relevant). When I use the code below, I do not read in the text (though I do read in html, if pointed to a url that has html).
String text = "RESULTS:\n";
try {
String urlString =
"http://appdata.mysite.com/httpauth/" +
"hub/DAR_param1_RTQB?" +
"method=query&list=param2";
// Create a URL
URL url = new URL(urlString);
// Read all the text returned by the server
in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
text = text + line;
}
} catch (MalformedURLException e) {
} catch (IOException e) {
} catch (Exception e) {
} finally {
if ( in != null ) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, "Exception trying to close BufferedReader");
}
}
}
return text;
This returns only "RESULTS:", but none of the text. What am I missing?
Edit: Here is an example of the file. This is displayed in a browser if the url is pasted into the address bar:
20120120_1734
20120120_1725
20120120_1715
20120120_1705
20120120_1655
You are swallowing all the potential errors that you need to see to troubleshoot this.
In your catch clauses, try adding some code to see the errors.
Something along the lines of:
System.out.println("Error: ", e.getMessage());
Did you add the Internet permissions in the manifest? The code looks fine, but you're clearly getting some error and not outputting the errors since you dont have a print message in the catch clause.
Log.i("--->","e.getMessage()); //just like oldingn said
With your suggestions given on this thread,
I tried using FileLock, however, when I write something in the file, somehow excel file gets corrupted and there is nothing in the file (it gets empty, no contents in there)
I have the following method:
void writeIntoTheFile(XSSFWorkbook defectWorkBook, File fileToWrite) {
FileLock lock = null;
FileChannel channel = null;
FileOutputStream out = null;
try {
//fileToWrite contains an excel .xlsx file
channel = new RandomAccessFile(fileToWrite, "rw").getChannel();
lock = channel.tryLock();
if (lock != null) {
out = new FileOutputStream(fileToWrite.getPath());
defectWorkBook.write(out);
} else {
JOptionPane.showMessageDialog(null, "Another instance is already writing, Try after a few seconds.", "Write Error...", JOptionPane.INFORMATION_MESSAGE);
}
out.close();
} catch (Exception e) {
e.getMessage();
}
finally{
if (lock != null && lock.isValid()) {
lock.release();
}
channel.close();
}
}
Seems the problem is coming from below code:
channel = new RandomAccessFile(fileToWrite, "rw").getChannel();
lock = channel.tryLock();
Can anyone please help me on this issue?
rahul
I suspect you are getting an exception in your try{} block, but your catch clock doesn't prin it. e.getMessage() will get the message but not print it.
I suggest something along the lines of e.printStackTrace() (for a production system you would want to do something more useful with the exception).
Wrote up a basic file handler for a Java Homework assignment, and when I got the assignment back I had some notes about failing to catch a few instances:
Buffer from file could have been null.
File was not found
File stream wasn't closed
Here is the block of code that is used for opening a file:
/**
* Create a Filestream, Buffer, and a String to store the Buffer.
*/
FileInputStream fin = null;
BufferedReader buffRead = null;
String loadedString = null;
/** Try to open the file from user input */
try
{
fin = new FileInputStream(programPath + fileToParse);
buffRead = new BufferedReader(new InputStreamReader(fin));
loadedString = buffRead.readLine();
fin.close();
}
/** Catch the error if we can't open the file */
catch(IOException e)
{
System.err.println("CRITICAL: Unable to open text file!");
System.err.println("Exiting!");
System.exit(-1);
}
The one comment I had from him was that fin.close(); needed to be in a finally block, which I did not have at all. But I thought that the way I have created the try/catch it would have prevented an issue with the file not opening.
Let me be clear on a few things: This is not for a current assignment (not trying to get someone to do my own work), I have already created my project and have been graded on it. I did not fully understand my Professor's reasoning myself. Finally, I do not have a lot of Java experience, so I was a little confused why my catch wasn't good enough.
Buffer from file could have been null.
The file may be empty. That is, end-of-file is reach upon opening the file. loadedString = buffRead.readLine() would then have returned null.
Perhaps you should have fixed this by adding something like if (loadedString == null) loadedString = "";
File was not found
As explained in the documentation of the constructor of FileInputStream(String) it may throw a FileNotFoundException. You do catch this in your IOException clause (since FileNotFoundException is an IOException), so it's fine, but you could perhaps have done:
} catch (FileNotFoundException fnfe) {
System.err.println("File not fonud!");
} catch (IOException ioex {
System.err.println("Some other error");
}
File stream wasn't closed
You do call fin.close() which in normal circumstances closes the file stream. Perhaps he means that it's not always closed. The readLine could potentially throw an IOException in which case the close() is skipped. That's the reason for having it in a finally clause (which makes sure it gets called no matter what happens in the try-block. (*)
(*) As #mmyers correctly points out, putting the close() in a finally block will actually not be sufficient since you call System.exit(-1) in the catch-block. If that really is the desired behavior, you could set an error flag in the catch-clause, and exit after the finally-clause if this flag is set.
But what if your program threw an exception on the second or third line of your try block?
buffRead = new BufferedReader(new InputStreamReader(fin));
loadedString = buffRead.readLine();
By this point, a filehandle has been opened and assigned to fin. You could trap the exception but the filehandle would remain open.
You'll want to move the fin.close() statement to a finally block:
} finally {
try {
if (fin != null) {
fin.close();
}
} catch (IOException e2) {
}
}
Say buffRead.readLine() throws an exception, will your FileInputStream ever be closed, or will that line be skipped? The purpose of a finally block is that even in exceptional circumastances, the code in the finally block will execute.
There are a lot of other errors which may happen other than opening the file.
In the end you may end up with a fin which is defined or not which you have to protect against null pointer errors, and do not forget that closing the file can throw a new exception.
My advice is to capture this in a separate routine and let the IOExceptions fly out of it :
something like
private String readFile() throws IOException {
String s;
try {
fin = new FileInputStream(programPath + fileToParse);
buffRead = new BufferedReader(new InputStreamReader(fin));
s = buffRead.readLine();
fin.close();
} finally {
if (fin != null {
fin.close()
}
}
return s
}
and then where you need it :
try {
loadedString = readFile();
} catch (IOException e) {
// handle issue gracefully
}