Java.io.FileNotFoundException: /storage/emulated/0/saved_images/grub.jpg: 打开失败: ENOENT(没有这样的文件或目录)

24

我正在使用以下代码将一张图片保存到SD卡中,但是我一直收到如下异常:

private void SaveImage(Bitmap finalBitmap,String filename) {

    String root = Environment.getExternalStorageDirectory().toString();
    File myDir = new File(root + "/saved_images");    
    myDir.mkdirs();

    String fname = filename;
    File file = new File (myDir, fname);
    if (file.exists ()) file.delete (); 
    try {
           FileOutputStream out = new FileOutputStream(file);
           finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
           out.flush();
           out.close();

    } catch (Exception e) {
           e.printStackTrace();
    }
}

我有什么遗漏吗?


1
我通过请求用户权限来修复了相同的错误消息。如果您正在使用 SDK > 22,则必须这样做。您可以在这里的一个答案中找到完整的代码。 - João Cartucho
6个回答

17

修改您的代码,因为您没有创建目录:

 private void SaveImage(Bitmap finalBitmap,String filename) {

    String root = Environment.getExternalStorageDirectory().toString();
    File myDir = new File(root + "/saved_images");    
    myDir.mkdirs();

    String fname = filename;
    File file = new File (myDir, fname);
    if (file.exists ()) file.delete (); 
    file.createNewFile();
    try {
           FileOutputStream out = new FileOutputStream(file);
           finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
           out.flush();
           out.close();

    } catch (Exception e) {
           e.printStackTrace();
    }
}

2
你怎么能不在 "file.createNewFile();" 周围加上 try 和 catch 呢? - Red M

17
如果您在Android 10版本中遇到此问题,则打开清单文件并将此行添加到应用标记中。
<application android:requestLegacyExternalStorage="true" .....>

这个问题是因为 Android 10 引入了 scoped storage。请确保您在清单中添加权限请求,并从用户处获取运行时权限。在最新的 Android 版本中,您需要从用户那里获取运行时权限。


5

从SDK版本30开始,您不能使用android:requestLegacyExternalStorage="true"扩展。相反,您需要对ImageLoader库进行一些修改。我看到您需要修改文件路径:File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "saved_images");变成类似这样的内容:File dir = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "saved_images");。这应该就可以解决问题了。


运作得很好!@Vaidas - AndroidManifester

2

当我在检查文本文件中的时间戳时,这是我从存储中读取文件的方式。第2行可能是最好的选择。

File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/path");
dir.mkdirs();
File file = new File(dir, ".storage.txt");
Reader pr;
String line = "";
try {
    pr = new FileReader(file);
    int data = pr.read();
        while (data != -1) {
            line += (char) data;
            data = pr.read();
        }
    pr.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
//do stuff with line

1
从Android 6.0.0开始,您需要使用以下代码:
if (ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)

0

请确保您在清单文件中设置了权限:

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

"android.permission.WRITE_EXTERNAL_STORAGE" 已在 Android 11 (API 级别 30) 中被移除。 - Anis LOUNIS aka AnixPasBesoin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接