Search code examples
javaandroidandroid-studioexceptionfileinputstream

java.io.FileNotFoundException: /sdcard/...: open failed: EISDIR (Is a directory)


hello I'm trying to upload a file to my application and on some devices for uploading from sdcard it gives me an error:java.io.FileNotFoundException: (path in sdcard): open failed: EISDIR (Is a directory). anybody have any idea why?? My code:

browsing file and opening file manager:

 private void doBrowseFile()  {
    Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
    chooseFileIntent.setType("application/pdf");
    // Only return URIs that can be opened with ContentResolver
    chooseFileIntent.addCategory(Intent.CATEGORY_OPENABLE);

    chooseFileIntent = Intent.createChooser(chooseFileIntent, "Choose a file");
    startActivityForResult(chooseFileIntent, UNIQUE_REQUEST_CODE);
} 

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == UNIQUE_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            if (data != null) {
                Uri fileUri = data.getData();
                Log.i(LOG_TAG, "Uri: " + fileUri);

                String filePath = null;
                try {
                    filePath = FileUtils.getPath(this, fileUri);
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Error: " + e);
                    Toast.makeText(this, "Error: " + e, Toast.LENGTH_SHORT).show();
                }
                getBase64FromPath(filePath);
            }
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Encoding file from file path:

@RequiresApi(api = Build.VERSION_CODES.O)
public void getBase64FromPath(String path) {
    String base64 = "";
    try {
        File file = new File(path);
        byte[] buffer = new byte[(int) file.length() + 100];
        file.getParentFile().mkdirs();
        FileInputStream fileInputStream = new FileInputStream(file); //THIS LINE GIVES ME ERROR
        @SuppressWarnings("resource")
        int length = fileInputStream.read(buffer);
        base64 = Base64.encodeToString(buffer, 0, length,
                Base64.DEFAULT);
        uploadFile(base64);
    } catch (IOException e) {
        Toast.makeText(this, "error:" + e.getMessage() , Toast.LENGTH_SHORT).show();
    }

}

If anybody know any idea why please tell. It gives this error on some devices only. on the others it works perfectly fine. thanks.


Solution

  • Get rid of FileUtils.getPath(), as it will never work reliably.

    You can get an InputStream on your content by calling getContentResolver().openInputStream(fileUri). You can then use that InputStream instead of the FileInputStream to read in your content.

    Note that your app will crash with an OutOfMemoryError with large PDFs. I strongly recommend that you find some way to upload your content without reading it all into memory at once. For example, you might consider not converting it to base-64.