Java 文件处理,我做错了什么?

发布于 2024-09-03 09:30:16 字数 1021 浏览 2 评论 0原文

为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迷迭香的记忆 2024-09-10 09:30:16
  • 文件中的缓冲区可能为空。

文件可能为空。也就是说,打开文件时就到达文件结尾。 loadedString = buffRead.readLine() 将返回 null。

也许您应该通过添加类似 if (loadedString == null) returnedString = ""; 的内容来解决此问题

  • 找不到文件

正如 FileInputStream(String) 构造函数的文档中所述,它可能会抛出 FileNotFoundException。您确实在 IOException 子句中捕获了这个(因为 FileNotFoundException 是一个 IOException),所以它很好,但是您也许可以这样做:

} catch (FileNotFoundException fnfe) {
    System.err.println("File not fonud!");
} catch (IOException ioex {
    System.err.println("Some other error");
}
  • 文件流未关闭

您确实调用了fin.close(),它在正常情况下会关闭文件流。也许他的意思是它并不总是关闭的。 readLine 可能会抛出 IOException,在这种情况下,close() 会被跳过。这就是将其放在 finally 子句中的原因(这确保无论 try 块中发生什么情况都会调用它。(*)


(*) As @mmyers正确地指出,将 close() 放在 finally 块中实际上是不够的,因为您在中调用 System.exit(-1) catch 块。如果这确实是所需的行为,您可以在 catch 子句中设置一个错误标志,并在设置了该标志后在 finally 子句后退出。

  • 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.

ゝ偶尔ゞ 2024-09-10 09:30:16

但是,如果您的程序在 try 块的第二行或第三行抛出异常怎么办?

buffRead = new BufferedReader(new InputStreamReader(fin));
loadedString = buffRead.readLine();

至此,一个文件句柄已被打开并分配给fin。您可以捕获异常,但文件句柄将保持打开状态。

您需要将 fin.close() 语句移至 finally 块:

} finally {
    try {
        if (fin != null) {
            fin.close();
        }
    } catch (IOException e2) {
    }
}

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) {
    }
}
小红帽 2024-09-10 09:30:16

假设 buffRead.readLine() 抛出异常,您的 FileInputStream 是否会被关闭,或者该行是否会被跳过? finally 块的目的是,即使在特殊情况下,finally 块中的代码也将执行。

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.

白龙吟 2024-09-10 09:30:16

除了打开文件之外,还可能发生许多其他错误。

最后,您可能会得到一个已定义或未定义的 fin,您必须保护它免受空指针错误的影响,并且不要忘记关闭文件可能会引发新的异常。

我的建议是在一个单独的例程中捕获它,并让 IOExceptions 飞出它:

类似于

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
}

然后在您需要它的地方:

try {
   loadedString = readFile();
} catch (IOException e) {
   // handle issue gracefully
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文