Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FilePickerPlugin.java does not close the output/input streams it opens #28

Closed
kinex opened this issue Jan 23, 2019 · 2 comments
Closed
Milestone

Comments

@kinex
Copy link

kinex commented Jan 23, 2019

FilePickerPlugin.java does not close any of the output or input streams it opens. For a sample how to do this correctly, see e.g. https://javarevisited.blogspot.com/2014/10/right-way-to-close-inputstream-file-resource-in-java.html

I think this is quite high level issue in this plugin. I see some random FileNotFoundExceptions in my app (for some users/devices this happens always). This is most probably caused by this issue in this plugin (accessing a file picked with this plugin fails because the file is still reserved by the plugin).

As a related comment, I am not sure is it a good idea to try/catch errors in the onActivityResult method. It will just hide errors, the error should be delivered to plugin caller.

@miguelpruivo
Copy link
Owner

Version 1.3.0 was deployed on dart pub and fixes this, alongside with other requested features and bug fixes. See changelog.

Make sure you clean and change your pubspec to the latest version: file_picker: ^1.3.0

Thank you for your feedback.

@kinex
Copy link
Author

kinex commented Sep 19, 2019

There are still issues in FileUtils.java / getUriFromRemote, it leaks memory and file handles. Here is sample how to do it correctly:

public static String getUriFromRemote(Context context, Uri uri, MethodChannel.Result result) {

    Log.i(TAG, "Caching file from remote/external URI");
    FileOutputStream fos = null;
    final String fileName = FileUtils.getFileName(uri, context);
    String externalFile = context.getCacheDir().getAbsolutePath() + "/" + (fileName != null ? fileName : new Random().nextInt(100000));
    InputStream in = null;
    BufferedOutputStream out = null;

    try {
        fos = new FileOutputStream(externalFile);
        out = new BufferedOutputStream(fos);
        in = context.getContentResolver().openInputStream(uri);

        byte[] buffer = new byte[8192];
        int len = 0;

        while ((len = in.read(buffer)) >= 0) {
            out.write(buffer, 0, len);
        }

        // these are probably not needed
        out.flush();
        fos.getFD().sync();
    } catch (Exception e) {
        Log.e(TAG, "Failed to retrieve path: " + e.getMessage(),null);
        return null;
    } finally {
        try { if (in != null) in.close(); } catch(IOException e) {} 
        try { if (out != null) out.close(); } catch(IOException e) {}
        try { if (fos != null) fos.close(); } catch(IOException e) {}
    }

    Log.i(TAG, "File loaded and cached at:" + externalFile);
    return externalFile;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants