BufferedInputStream或FileInputStream IOException

时间:2015-11-06 15:33:37

标签: android ioexception fileinputstream bufferedinputstream

我刚刚发布了一个Android应用程序,它解析本地文件并对数据进行一些处理。 几天前,我的一位客户报告了一个错误,每当他试图处理他的文件时应用程序崩溃。

这是他发给我的错误日志:

java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:300)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: lock == null
    at java.io.Reader.<init>(Reader.java:64)
    at java.io.InputStreamReader.<init>(InputStreamReader.java:120)

与此相关的代码是:

// EDIT 1: Following greenapps comment I will put a more realistic version of this 
// method (The first version was invented because I wanted to be breaf)
public void selectFile()
{
    List<File> files = getDocsToParse();
    this.listview.setAdapter(this.myadapter);
    this.listview.setOnItemClickListener(new OnItemClickListener()
    {
        ...
        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        parseFile(files.get(position));
                }
        ...
    }
    this.myadapter.addFiles(files);
}

public static List<File> getDocsToParse() {
    File sdcard = Environment.getExternalStorageDirectory();
    File subdir = new File(sdcard, "MyAppFolder/Files/");
    // EDIT 2: I'm using  subdir.mkdirs(); because I want to 
    // create MyAppFolder/Files/ folders the first time the user use the app. 
    // Is this not correct? Should I create these folders any other way? 
    if (!subdir.exists()) {
        subdir.mkdirs();
    }
    File files[] = subdir.listFiles();
    List<File> filterFiles = new ArrayList<File>();
    for (int i = 0; i < files.length; i++) {
        File file = files[i];
        filterFiles.add(file);
    }
    return filterFiles;
}

public void parseFile(File fileToParse)
{
    long totalSize = 0;
    InputStream is = null;
    try {
            totalSize = fileToParse.length();
            is = new BufferedInputStream(new FileInputStream(fileToParse));
    } catch (IOException e) {
        e.printStackTrace();
    }
    BufferedReader reader = null;
    reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
    String line = "";
    StringTokenizer st = null;
    try {
        while ((line = reader.readLine()) != null) {
           // Here I parse the file
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

崩溃的线是这一行:

reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));

我明白这是因为“是”是空的,我应该抓住这个案例,以避免应用程序崩溃(我将在我的下一个版本中解决这个问题)。

编辑3:你是对的,greenapps,我会在使用之前检查是否为null,在其他情况下我不会使用它。

我知道“is”是null,因为有一个IOException这样做:

 totalSize = fileToParse.length();
    is = new BufferedInputStream(new FileInputStream(fileToParse));

编辑4:当然,如果这给了我一个IOEXception,我将不得不改变我的代码来做一个完全不同的事情。

我无法在Internet上找到原因,因此这两行代码可能会抛出IOException。

认为fileToParse没问题,或者至少不是null,因为我将这个“文件”列表传递给适配器,用files.get(i).getName()显示文件名,并正确显示名称

我必须补充说,要处理的文件非常大并且具有敏感的个人数据,因此用户无法将其发送给我,因此我可以使用它进行测试。

我的文件都没有给我这个错误,如果没有有问题的文件,我很难跟踪问题所以我不得不猜测。知道什么原因会导致这个错误?

非常感谢和亲切的问候!

编辑5:遵循ctarabusi建议我已将我的parseFile方法更改为:

public void parseFile(File fileToParse)
{
    long totalSize = 0;
    InputStream is = null;
    try {
            totalSize = fileToParse.length();
            is = new BufferedInputStream(new FileInputStream(fileToParse));
            BufferedReader reader = null;
            reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
            String line = "";
            StringTokenizer st = null;
            while ((line = reader.readLine()) != null) {
               // Here I parse the file
            }
    } catch (IOException e) {
          Toast.makeText(getApplicationContext(), "Error parsing file", Toast.LENGTH_LONG).show();
        e.printStackTrace();
    } finally {
        if(is != null)
        {
            try
            {
                is.close();
            }
            catch (IOException e)
            {
                Log.e("", e.getMessage(), e);
            }
        }
    }
}

我的测试再次正常运行,但是用户告诉我他看到了“解析文件时出错”消息,所以它还没有失败。

我还能检查什么?

1 个答案:

答案 0 :(得分:0)

可能是您的问题是您没有关闭输入流。 文件描述符和流是有限的资源,完成它们后释放它们非常重要。

通常在finally块中完成,如:

InputStream inputStream = null;
try 
{
    ... use your input stream
}
catch (IOException e)
{
    Log.e(TAG, e.getMessage(), e);
}
finally
{
    if (inputStream != null)
    {
        try
        {
            inputStream.close();
        }
        catch (IOException e)
        {
            Log.e(TAG, e.getMessage(), e);
        }
    }
}
相关问题