[英]Handling IO exceptions in Java
基本上,我想打开一个文件,读取一些字节,然后关闭该文件。 这就是我想出的:
try
{
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
try
{
// ...
inputStream.read(buffer);
// ...
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try
{
inputStream.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
也许我被 RAII 宠坏了,但在 Java 中一定有更好的方法来做到这一点,对吧?
如果您对IOException
和FileNotFoundException
有相同的异常处理代码,那么您可以只用一个catch
子句以更紧凑的方式重写您的示例:
try {
InputStream input = new BufferedInputStream(new FileInputStream(file));
try {
// ...
input.read(buffer);
// ...
}
finally {
input.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
如果您可以传播可能比手动打印堆栈跟踪更有意义的异常,您甚至可以摆脱外部try-catch
。 如果您没有在程序中捕获一些异常,您将自动为您打印堆栈跟踪。
此外,需要手动关闭 stream 将在 Java 7 中通过自动资源管理得到解决。
通过自动资源管理和异常传播,代码减少到以下内容:
try (InputStream input = new BufferedInputStream(new FileInputStream(file))) {
// ...
input.read(buffer);
// ...
}
通常这些方法都包含在库中。 除非您想在此级别编写,否则最好创建自己的辅助方法或使用现有的方法,如FileUtils 。
String fileAsString = Fileutils.readFileToString(filename);
// OR
for(String line: FileUtils.readLines(filename)) {
// do something with each line.
}
我不知道这是否正确,但是您可以将所有代码放在同一个 try 块中,然后将不同的 catch 块紧接在一起。
try {
...
}
catch (SomeException e) {
...
}
catch (OtherException e) {
...
}
如果您想在普通的 Java 中执行此操作,您发布的代码看起来还可以。
您可以使用 3rd 方库,例如 Commons IO,您需要在其中编写更少的代码。 例如
查看 Commons IO:
有时您可以将代码简化为以下内容:
public void foo(String name) throws IOException {
InputStream in = null;
try {
in = new FileInputStream(name);
in.read();
// whatever
} finally {
if(in != null) {
in.close();
}
}
}
当然,这意味着foo
的调用者必须处理IOException
,但无论如何大部分时间都应该是这种情况。 最后,您并没有真正减少那么多复杂性,但是由于嵌套的异常处理程序更少,代码变得更具可读性。
我在不使用实用程序的情况下对此的看法是:
InputStream inputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
// ...
inputStream.read(buffer);
// ...
} catch (IOException e) {
e.printStackTrace();
throw e; // Rethrow if you cannot handle the exception
} finally {
if (inputStream != null) {
inputStream.close();
}
}
不是单线,但也不是很糟糕。 例如,使用 Apache Commons IO 它将是:
//...
buffer = FileUtils.readFileToByteArray(file);
//...
要记住的是标准 Java 缺少许多这些小实用程序和每个人都需要的易于使用的界面,因此您必须依赖一些支持库,例如Apache Commons , Google Guava ,...在您的项目中,(或实现您的自己的实用程序类)。
使用org.apache.commons.io.FileUtils.readFileToByteArray(File)
或类似 package 的东西。 它仍然会抛出 IOException,但它会为您处理清理工作。
尝试以下操作:
try
{
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[1024];
try
{
// ...
int bytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
//Process the chunk of bytes read
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
inputStream.close();
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Google guava 试图通过引入Closeables来解决这个问题。
否则,您必须等到 JDK 7 的AutoCloseable出现,因为它解决了抛出 IOException 的一些情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.