【问题标题】:Releasing resources acquired by BufferedReader, InputStreamReader and InputStream释放 BufferedReader、InputStreamReader 和 InputStream 获取的资源
【发布时间】:2014-01-24 10:30:45
【问题描述】:

我有以下代码:

public ArrayList<Crime> loadCrimes() throws IOException, JSONException {
    ArrayList<Crime> crimes = new ArrayList<Crime>();
    BufferedReader reader = null;
    try {
        // Open and read the file into a StringBuilder
        InputStream in = mContext.openFileInput(mFilename);
        //what if an exception gets thrown in the line below?
        reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder jsonString = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            // Line breaks are omitted and irrelevant
            jsonString.append(line);
        }
        // Parse the JSON using JSONTokener
        JSONArray array = (JSONArray) new JSONTokener(jsonString.toString()).nextValue();
        // Build the array of crimes from JSONObjects
        for (int i = 0; i < array.length(); i++) {
            crimes.add(new Crime(array.getJSONObject(i)));
        }
    } catch (FileNotFoundException e) {
        // Ignore this one; it happens when starting fresh
    } finally {
        if (reader != null)
            reader.close();
        }
    return crimes;
}

首先,我想知道为什么我们只在 BufferedReader 对象上调用 .close() 而不是在 InputStreamInputStreamReader 对象上调用。我查看了 Oracle 官方文档并浏览了 stackoverflow 中的几个问题,根据我读过的内容,BufferedReader.close() 负责释放InputStreamReaderInputStream 获得的资源,所以我不必打电话.close() 他们。

这对吗?

其次,我想如果在创建InputStream 对象之后和创建BufferedReader 对象之前抛出异常会发生什么。也就是说,InputStreamReader(InputStream in) 构造函数或BufferedReader(Reader in) 构造函数都会引发异常。在这种情况下,我们获得了InputStream 的文件资源,但BufferedReader 对象仍然是null,因此在finally 块中,不会调用.close() 方法并且不会释放InputStream它获得的资源。

然后我阅读了 Oracle 文档,这两个构造函数都没有根据它抛出异常。所以这两行之间不可能发生异常吧?

我的最后一个问题是“这段代码是否确保它释放了它获得的所有资源?”

【问题讨论】:

    标签: java android exception resources


    【解决方案1】:

    首先,我想知道为什么我们只对 BufferedReader 对象而不是 InputStream 和 InputStreamReader 对象调用 .close()。我查看了 Oracle 官方文档并浏览了 stackoverflow 中的几个问题,根据我读过的内容,BufferedReader.close() 负责释放 InputStreamReader 和 InputStream 获取的资源,所以我不必调用 .close () 在他们。 这是正确的吗?

    是的。

    我的最后一个问题是“这段代码是否确保它释放了它获得的所有资源?”

    很可能,是的。即使在创建InputStreamReaderBufferedReader时出现一些奇怪的异常,在退出定义它们的块后,在GC收集它们之前,它们也会自动关闭。当然,依靠 GC 为您清理通常不是一个好主意,所以如果您想 100% 确定,您可能想在 finally 块中自己做。

    另一种更简单的方法是使用FileReader,这将通过仅使用两个对象来简化代码:

    BufferedReader reader = new BufferedReader(new FileReader(fileName));
    

    (我假设您想从文件中读取)。

    【讨论】:

    • 您的假设是正确的,我想从文件中读取,但我没有直接访问该文件的权限,因为此代码在 android 设备上执行。
    猜你喜欢
    • 1970-01-01
    • 2015-11-17
    • 2014-04-08
    • 2012-08-25
    • 2020-02-16
    • 2015-02-24
    • 2015-10-27
    • 2011-03-12
    • 1970-01-01
    相关资源
    最近更新 更多