错误:打开失败:ENOENT(没有这样的文件或目录)

时间:2016-03-18 15:46:57

标签: android

我试图创建一个文件来保存相机中的图片,但事实证明我无法创建该文件。 但我真的找不到错误。你能看看它并给我一些建议吗?

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

我已经添加了许可。

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

该方法总是会出现这样的错误:

  

打开失败:ENOENT(没有这样的文件或目录)

11 个答案:

答案 0 :(得分:37)

图片目录可能尚不存在。它不能保证在那里。

the API documentation for getExternalStoragePublicDirectory()中,代码使用mkdirs确保目录存在:

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

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

...所以它可能就像在你path.mkdirs()之前将createTempFile添加到现有代码一样简单。

答案 1 :(得分:7)

替换:

Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES)

使用:

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

请务必致电:

mkdirs() // and not mkdir()

这里有适合您的代码:

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

根据Android Studio Documentation中给出的示例,我遇到了不好的经历,我发现在stackoverflow中有很多其他人对此特定主题有相同的看法,这是因为即使我们设置了

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

某些设备问题仍然存在。

我的经验是,当我在调试模式下尝试它时,该示例有效,经过3次测试后,我的SD突然被破坏了,但我不认为这与他们的例子有关(搞笑) )。我买了一张新的SD卡并再次尝试,只是意识到发布和调试模式仍然执行相同的错误日志:目录不存在ENOENT。最后,我不得不自己创建目录,其中包含我手机摄像头拍摄的照片。我是对的,它的工作非常完美。

我希望这有助于你和其他人在那里寻找答案。

答案 2 :(得分:7)

当用户从图库中选择文件时,不能保证所选择的文件是由其他应用添加或编辑的。因此,如果用户选择的文件属于另一个应用程序,则会遇到权限问题。快速解决方案是将以下代码添加到AndroidManifest.xml文件中:

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

注意:适用于API级别29或更高版本

答案 3 :(得分:1)

我将contentResolver与URI一起使用,它对我有用。在另一个我找不到的SO帖子中看到它。

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;
}
希望它有所帮助......

答案 4 :(得分:1)

一个快速解决方案是在AndroidManifest.xml文件中添加以下代码:

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

注意:适用于API级别29或更高版本

答案 5 :(得分:0)

试试这个:

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

答案 6 :(得分:0)

我这样解决了:

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

答案 7 :(得分:0)

{
  "timestamp": [
    [
      "2020-04-07T13:08:19.261-0700"
    ]
  ],
  "loglevel": [
    [
      "|INFO"
    ]
  ]
}

答案 8 :(得分:0)

在将位图保存到外部目录时遇到了同样的错误,并且找到了有用的技巧

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
    }

但这有一个缺点,即您无法更改目录,它始终将图像保存到图片目录,但是如果您将其固定了,则可以自由填充以编辑我的代码: Haa-ha-ha {我无法在键盘上使用表情符号},Good Day

答案 9 :(得分:0)

以下是我发现的修复 首先在您的 AndroidManifest 文件中添加这两行

在 setContentView 方法之后添加以下行

ActivityCompat.requestPermissions(FullImageActivity.this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_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();
    }

答案 10 :(得分:-1)

如果您正在使用Kotlin,请使用以下功能。 您必须提供存储图像的路径,位图(在这种情况下为图像),如果要降低图像的质量,请提供%age,即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()
    }

希望它能工作。