Error: open failed: ENOENT (No such file or directory)

Android

Android Problem Overview


I was trying to create a file to save pictures from the camera, it turns out that I can't create the file. But I really can't find the mistake. Can you have a look at it and give me some advice?

    private File createImageFile(){
            File imageFile=null;
            String stamp=new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            File dir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            String imageFileName="JPEG_"+stamp+"_";
            try {
                imageFile=File.createTempFile(imageFileName,".jpg",dir);
            } catch (IOException e) {
                Log.d("YJW",e.getMessage());
            }
            return  imageFile;
        }

And I have added the permission.

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

The method always gives such mistakes:

>open failed: ENOENT (No such file or directory)

Android Solutions


Solution 1 - Android

The Pictures directory might not exist yet. It's not guaranteed to be there.

In the API documentation for getExternalStoragePublicDirectory(), the code ensures the directory exists using mkdirs:

File path = Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");

try {
    // Make sure the Pictures directory exists.
    path.mkdirs(); 

...so it may be as simple as adding that path.mkdirs() to your existing code before you createTempFile.

Solution 2 - Android

when a user picks a file from the gallery, there is no guarantee that the file that was picked was added or edited by some other app. So, if the user picks on a file that let’s say belongs to another app we would run into the permission issues. A quick fix for that is to add this code in the AndroidManifest.xml file:

<manifest ... >
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

Note: For Android 11 refer Scope storage Enforcement Policy https://developer.android.com/about/versions/11/privacy/storage

Solution 3 - Android

Replace:

Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES)

With:

private File createImageFile() throws IOException {
        // Create an image file name

make sure you call:

mkdirs() // and not mkdir()

Here's the code that should work for you:

        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = new File(Environment.getExternalStorageDirectory().toString(), "whatever_directory_existing_or_not/sub_dir_if_needed/");
        storageDir.mkdirs(); // make sure you call mkdirs() and not mkdir()
        File image = File.createTempFile(
                imageFileName,  // prefix
                ".jpg",         // suffix
                storageDir      // directory
        );

        // Save a file: path for use with ACTION_VIEW intents

        mCurrentPhotoPath = "file:" + image.getAbsolutePath();
        Log.e("our file", image.toString());
        return image;
    }

I had a bad experience following the example given in Android Studio Documentation and I found out that there are many others experiencing the same about this particular topic here in stackoverflow, that is because even if we set

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

the problem persists in some devices.

My experience was that the example worked when I tried it in debug mode, after that 3 more tests it so happened that my SD suddenly was corrupted, but I don't think it has to do with their example (funny). I bought a new SD card and tried it again, only to realize that still both release and debug mode did the same error log: directory does not exist ENOENT. Finally, I had to create the directories myself whick will contain the captured pictures from my phone's camera. And I was right, it works just perfect.

I hope this helps you and others out there searching for answers.

Solution 4 - Android

A quick fix for that is to add this code in the AndroidManifest.xml file:

<manifest ... >
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

Note: Applicable for API level 29 or Higher

Solution 5 - Android

I used the contentResolver with the URI and it worked for me. Saw it in another SO post which i can't find.

private String getRealPathFromURI(Uri contentURI) {
    String result;
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) {
        result = contentURI.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}

hope it helps....

Solution 6 - Android

I have solved like this:

        public Intent getImageCaptureIntent(File mFile) {
             Intent mIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
             Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", mFile);
             mIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
        
             // The tip is this code below
             List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY);
                 for (ResolveInfo resolveInfo : resInfoList) {
                      String packageName = resolveInfo.activityInfo.packageName;
                      grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                 }
    
             return  mIntent;
        }

Solution 7 - Android

If you are using kotlin then use below function. you have to provide a path for storing image, a Bitmap (in this case a image) and if you want to decrease the quality of the image then provide %age i.e 50%.

fun cacheLocally(localPath: String, bitmap: Bitmap, quality: Int = 100) {
        val file = File(localPath)
        file.createNewFile()
        val ostream = FileOutputStream(file)
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, ostream)
        ostream.flush()
        ostream.close()
    }

hope it will work.

Solution 8 - Android

Try this:

private File createImageFile() throws IOException {  

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());  

    String imageFileName="JPEG_"+stamp+".jpg";  

    File photo = new File(Environment.getExternalStorageDirectory(),  imageFileName);  

    return photo;
}  

Solution 9 - Android

File dirPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = new File(dirPath, "YourPicture.jpg");

try {
    if(!dirPath.isDirectory()) {
       dirPath.mkdirs(); 
    } 
    imageFile.createNewFile();
  
} catch(Exception e) {
    e.printStackTrace();
}

Solution 10 - Android

I got same error while saving Bitmap to External Directory and found a helpful trick

private void save(Bitmap bitmap) {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    String imageFileName = timeStamp + ".png";
    String path = MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, imageFileName, null);
    Uri uriimage = Uri.parse(path);
    // you made it, make  fun
    }

But this have a drawback i.e. you cant change the Directory it always save images to Pictures directory but if you got it fixed fill free to edit my code: Haa-ha-ha {I can't use emojis with my keyboard}, Good Day

Solution 11 - Android

Following are fixes i found first add these two lines in your AndroidManifest file

Than add the below line just after setContentView method

ActivityCompat.requestPermissions(FullImageActivity.this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_CODE);

and for saving the images in gallery use the below code

private void SaveImageToGallery() {
        BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
        Bitmap bitmap = drawable.getBitmap();
        FileOutputStream outputStream = null;
        File file = Environment.getExternalStorageDirectory();
        File dir = new File(file.getAbsolutePath()+"/folderName");
        dir.mkdirs();
        String filename = String.format("%d.jpg",System.currentTimeMillis());
        File outfile = new File(dir,filename);
        try{
            outputStream = new FileOutputStream(outfile);
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,outputStream);
            outputStream.flush();
            outputStream.close();
        }catch(Exception e){
            Log.d("SavingError", "SaveImageToGallery: "+e.getMessage());
        }
        Toast.makeText(this, "Image saved in folderName folder", Toast.LENGTH_SHORT).show();
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJiawei YangView Question on Stackoverflow
Solution 1 - AndroidMatt GibsonView Answer on Stackoverflow
Solution 2 - AndroidBhavesh MoradiyaView Answer on Stackoverflow
Solution 3 - AndroidOBLView Answer on Stackoverflow
Solution 4 - Androidibrahim albitarView Answer on Stackoverflow
Solution 5 - AndroidperesisUserView Answer on Stackoverflow
Solution 6 - AndroidlucasddanielView Answer on Stackoverflow
Solution 7 - AndroidSachidananda SahuView Answer on Stackoverflow
Solution 8 - AndroidGovinda PaliwalView Answer on Stackoverflow
Solution 9 - AndroidLuvnish MongaView Answer on Stackoverflow
Solution 10 - AndroidSachidanand NavikView Answer on Stackoverflow
Solution 11 - AndroidWaseem KhanView Answer on Stackoverflow