Java 文件处理,我做错了什么?
为 Java 家庭作业编写了一个基本的文件处理程序,当我拿回作业时,我收到了一些关于未能捕获一些实例的注释:
- 文件中的缓冲区可能为空。
- 未找到
- 文件 文件流未关闭
这是用于打开文件的代码块:
/**
* 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);
}
我从他那里得到的一条评论是 fin.close();
需要位于一个 finally
块,我根本没有。但我认为我创建 try/catch 的方式可以防止文件无法打开的问题。
让我澄清几件事:这不是当前的作业(不是试图让某人做我自己的工作),我已经创建了我的项目并已对其进行评分。我自己并不完全理解教授的推理。最后,我没有太多的 Java 经验,所以我有点困惑为什么我的 catch
不够好。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
文件可能为空。也就是说,打开文件时就到达文件结尾。
loadedString = buffRead.readLine()
将返回 null。也许您应该通过添加类似
if (loadedString == null) returnedString = "";
的内容来解决此问题正如
FileInputStream(String)
构造函数的文档中所述,它可能会抛出FileNotFoundException
。您确实在IOException
子句中捕获了这个(因为FileNotFoundException
是一个IOException
),所以它很好,但是您也许可以这样做:您确实调用了
fin.close()
,它在正常情况下会关闭文件流。也许他的意思是它并不总是关闭的。readLine
可能会抛出IOException
,在这种情况下,close()
会被跳过。这就是将其放在finally
子句中的原因(这确保无论try
块中发生什么情况都会调用它。(*)(*) As @mmyers正确地指出,将
close()
放在finally
块中实际上是不够的,因为您在中调用System.exit(-1)
catch
块。如果这确实是所需的行为,您可以在 catch 子句中设置一个错误标志,并在设置了该标志后在 finally 子句后退出。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 = "";
As explained in the documentation of the constructor of
FileInputStream(String)
it may throw aFileNotFoundException
. You do catch this in yourIOException
clause (sinceFileNotFoundException
is anIOException
), so it's fine, but you could perhaps have done:You do call
fin.close()
which in normal circumstances closes the file stream. Perhaps he means that it's not always closed. ThereadLine
could potentially throw anIOException
in which case theclose()
is skipped. That's the reason for having it in afinally
clause (which makes sure it gets called no matter what happens in thetry
-block. (*)(*) As @mmyers correctly points out, putting the
close()
in afinally
block will actually not be sufficient since you callSystem.exit(-1)
in thecatch
-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.但是,如果您的程序在
try
块的第二行或第三行抛出异常怎么办?至此,一个文件句柄已被打开并分配给
fin
。您可以捕获异常,但文件句柄将保持打开状态。您需要将
fin.close()
语句移至finally
块:But what if your program threw an exception on the second or third line of your
try
block?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 afinally
block:假设 buffRead.readLine() 抛出异常,您的 FileInputStream 是否会被关闭,或者该行是否会被跳过?
finally
块的目的是,即使在特殊情况下,finally
块中的代码也将执行。Say
buffRead.readLine()
throws an exception, will yourFileInputStream
ever be closed, or will that line be skipped? The purpose of afinally
block is that even in exceptional circumastances, the code in thefinally
block will execute.除了打开文件之外,还可能发生许多其他错误。
最后,您可能会得到一个已定义或未定义的 fin,您必须保护它免受空指针错误的影响,并且不要忘记关闭文件可能会引发新的异常。
我的建议是在一个单独的例程中捕获它,并让 IOExceptions 飞出它:
类似于
然后在您需要它的地方:
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
and then where you need it :