释放BufferedReader,InputStreamReader和InputStream获取的资源

时间:2014-01-24 10:30:46

标签: java android exception resources

我有以下代码:

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;
}

首先,我想知道为什么我们只在.close()对象上调用BufferedReader,而不是在InputStreamInputStreamReader对象上调用BufferedReader.close()。我检查了官方的Oracle文档并浏览了stackoverflow中的几个问题,根据我读过的InputStreamReader负责发布InputStream.close()获取的资源,所以我不必在它们上面调用InputStream

这是对的吗?

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

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

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

1 个答案:

答案 0 :(得分:1)

  

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

是的,是的。

  

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

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

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

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

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