Android – bufferedinputstream or FileInputStream IOException

I just released an Android application that parses local files and processes some data. A few days ago, one of my customers reported an error. Every time he tried to process his files, the application crashed

This is the error log he sent me:

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)

The code related to this is as follows:

// 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();
    }
}

The broken line is this line:

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

I know this is because "yes" is empty. I should catch this case to avoid application crash (I will fix this problem in my next version)

Editor 3: you are right, greenapps. I will check whether it is null before using it. I won't use it in other cases

I know that "is" is null because there is an IOException that does this:

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

Editor 4: of course, if this gives me an IOException, I will have to change my code to make a completely different thing

I can't find the reason on the Internet, so these two lines of code may throw IOException

I think filetoparse is OK, or at least not null, because I pass this "file" list to the adapter, display their file names with files. Get (I). Getname(), and display the names correctly

I must add that the file to be processed is very large and has sensitive personal data, so users can't send it to me, so I can use it for testing

Without my file, it is difficult for me to track the problem, so I have to guess. Do you know what causes this error?

Thank you very much and kind regards!

Edit 5: following ctarabusi's advice, I have changed my parsefile method to:

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

My test works normally again, but the user told me he saw the "error parsing file" message, so it hasn't failed yet

What else can I check?

resolvent:

Perhaps your problem is that you did not close the input stream. File descriptors and streams are limited resources. It is very important to release them after they are completed

It is usually done in the finally block, such as:

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

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>