FileOutputStream crashes with "open failed: EISDIR (Is a directory)" error when downloading image
Asked Answered
R

5

40

I'm trying to download an iamge from the internet, Here is the code:

try {
                String imgURL = c.imgURL;
                String imgPATH = c.imgPATH;
                URL url = new URL(imgURL);
                URLConnection conexion = url.openConnection();
                conexion.connect();
                int lenghtOfFile = conexion.getContentLength();
                try {
                    File f = new File(imgPATH);
                    f.mkdirs();

                    BufferedInputStream input = new BufferedInputStream(url.openStream());
                    BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(imgPATH), 8192); // CRASH HERE

                    byte data[] = new byte[8192];
                    long total = 0;
                    int count = 0;
                    int updateUILimiter = 0;
                    while ((count = input.read(data)) != -1) {
                        total += count;

                        if (updateUILimiter == 20)
                            // publishProgress((int) (total * 100 / lenghtOfFile));
                            updateUILimiter = 0;
                        else
                            updateUILimiter++;

                        output.write(data, 0, count);

                        if (isCancelled()) {
                            output.flush();
                            output.close();
                            input.close();
                            return null;
                        }

                    }
                    output.flush();
                    output.close();
                    input.close();
                } catch (Exception e) {
                    c.imgPATH = "";
                    return null;
                }


            } catch (Exception e) {
                c.imgPATH = "";
                return null;
            }

Here is the error message:

/mnt/sdcard/tmp/3.png: open failed: EISDIR (Is a directory)

Why is this?

" /mnt/sdcard/tmp/" exists.

Roark answered 9/9, 2012 at 13:54 Comment(1)
Because 3.png is a directory?Supralapsarian
I
104

3.png is a directory, because you make it so by calling f.mkdirs();. Try f.getParentFile().mkdirs() instead. From the documentation:

Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories.

(emphasis mine). In other words, the entire path contained in the File instance f is taken to be a directory name, up to and including the final part (3.png in the example output).

Icily answered 9/9, 2012 at 14:14 Comment(1)
@MrLore: this is not equivalent. In particular, it does not make sure, that the intended target directory exists. Also, it may be intentional, that the code overwrites existing files (a case, where createNewFile would fail)Icily
R
19

The problem is that you are using the function

f.mkdirs();

this function will create a folder called "3.png" instead of a file called "3.png", so delete this folder first,

enter image description here

then replace the function

f.mkdirs();

to

f.createNewFile();

Hope this help.

Religiose answered 11/3, 2015 at 4:39 Comment(0)
C
5

replace f.mkdirs() with f.createNewFile().

Credit answered 25/12, 2013 at 6:56 Comment(0)
R
2

You can first make the directory and then further write the code.

 URL downloadURL=null;
    HttpURLConnection urlConnection=null;
    InputStream inputStream=null;
    FileOutputStream fos=null;
    Uri uri=Uri.parse(url);
    try {
        downloadURL=new URL(url);
        urlConnection= (HttpURLConnection) downloadURL.openConnection();
        inputStream=urlConnection.getInputStream();
        File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()+"/myAppImages/");
        if(!file.exists())
        {
            file.mkdirs();
        }
        File file1=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()+"/myAppImages/"+uri.getLastPathSegment());
        fos=new FileOutputStream(file1);
        byte[] buffer=new byte[1024];

        int read=-1;
        while((read=inputStream.read(buffer))!=-1)
        {
           /* Message.L(""+read);*/
            fos.write(buffer,0,read);
        }

    }

Like this you can do

File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()+"/myAppImages/");
        if(!file.exists())
        {
            file.mkdirs();
        }
        File file1=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()+"/myAppImages/"+uri.getLastPathSegment());
        fos=new FileOutputStream(file1);
Rat answered 8/11, 2016 at 16:37 Comment(0)
S
0

I encounter with this problem when <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> was not written correctly, so check manifest again.

Shearwater answered 10/10, 2022 at 12:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.