【问题标题】:FileNotFoundException: /storage/emulated/0/JsonParseTutorialCache: open failed: ENOENT (No such file or directory)FileNotFoundException:/storage/emulated/0/JsonParseTutorialCache:打开失败:ENOENT(没有这样的文件或目录)
【发布时间】:2016-10-26 10:56:44
【问题描述】:

我正在使用 GridView 加载包含图像的 json 数据。当我构建项目时,它发生了一些异常

AndroidManifest.xml:

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

FileCache 类:

public class FileCache {

private File cacheDir;

public FileCache(Context context) {
    // Find the dir to save cached images
    if (android.os.Environment.getExternalStorageState().equals(
            android.os.Environment.MEDIA_MOUNTED))
        cacheDir = new File(
                android.os.Environment.getExternalStorageDirectory(),
                "JsonParseTutorialCache");
    else
        cacheDir = context.getCacheDir();
    if (!cacheDir.exists())
        cacheDir.mkdirs();
}

public File getFile(String url) throws IOException {
    String filename = String.valueOf(url.hashCode());
    // String filename = URLEncoder.encode(url);
    File f = new File(cacheDir, filename);
    f.createNewFile();
    return f;
}

public void clear() {
    File[] files = cacheDir.listFiles();
    if (files == null)
        return;
    for (File f : files)
        f.delete();
 }

}

Logcat:

W/System.err: java.io.IOException: open failed: ENOENT (No such file or directory)
W/System.err:     at java.io.File.createNewFile(File.java:939)
W/System.err:     at    com.totoroads.android.app.FileCache.getFile(FileCache.java:33) 
W/System.err:     at com.totoroads.android.app.ImageLoader.getBitmap(ImageLoader.java:64)
W/System.err:     at com.totoroads.android.app.ImageLoader.access$000(ImageLoader.java:29)
W/System.err:     at com.totoroads.android.app.ImageLoader$PhotosLoader.run(ImageLoader.java:155)
W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
W/System.err:     at libcore.io.Posix.open(Native Method)
W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
W/System.err:     at java.io.File.createNewFile(File.java:932)
W/System.err:   ... 9 more

我想在 GridView 上下载、读取和显示图像,如何修复这些异常?

【问题讨论】:

  • "/storage/emulated/0/JsonParseTutorialCache/-1068682472" 我认为这不是图像的有效文件路径。您应该检查是否正确获取文件名。
  • 我通过参数获取图片是:TAG_ICONNAME="image"(from json)
  • 请也发布一个示例 json 响应。
  • @TheAbsurd:我更新了更多 FileCache 类和 JSON,请在上面查看

标签: java android gridview


【解决方案1】:

就我而言,它是:

如果面向 Android 10(API 级别 29)或更高版本,请在应用的 AndroidManifest 文件中将 requestLegacyExternalStorage 的值设置为 true

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

【讨论】:

  • 太棒了..这确实是我的问题,尽管在运行时获得了 WRITE_EXTERNAL_STORAGE 权限,但我无法创建目录。
  • 我也是这样。非常感谢您的帮助。
  • 仅供参考,上面的答案是解决问题的捷径。但是,在升级到 android 11 之前,您应该将数据从本地迁移到范围存储。您可以在此处查看如何迁移:developer.android.com/training/data-storage/…
【解决方案2】:

FileCache.java 中的代码是

public File getFile(String url) {
    String filename = String.valueOf(url.hashCode());
    // String filename = URLEncoder.encode(url);
    File f = new File(cacheDir, filename);
    return f;
}

已创建新文件对象,但该文件可能不存在。因此,将上面的代码替换为

public File getFile(String url) {
    String filename = String.valueOf(url.hashCode());
    // String filename = URLEncoder.encode(url);
    File f = new File(cacheDir, filename);
    f.createNewFile();
    return f;
}

希望,它会有所帮助。

编辑:当您在 >= Android 6.0 上运行代码时,您必须请求在运行时访问外部存储的权限。在 AndroidManifest.xml 中添加这些是不够的。您可以使用this link 了解如何操作。

【讨论】:

  • @TheAburd:我已经更新为你的代码,似乎是同样的错误,你可以看到Logcat
  • 您是否在 Marshmallow 或更高版本中运行此代码?
  • 我没有明确你的问题,但是我的代码是在开发环境(android studio)上运行的
  • 棉花糖:Nexus 5x API 23(Android 6,API 23)
【解决方案3】:

您可以使用 Picasso 库在网格视图中显示图像。 它为加载图像提供了一行代码。 使用库函数加载图像--

Picasso.with(context).load("YOURIMAGE").into(imageView);

您还可以根据需要调整图像大小。 也是内部管理缓存机制

更多信息请参考链接 - http://square.github.io/picasso/

【讨论】:

  • 我会尽力回复你
  • 感谢您对毕加索的建议,它对我有用
【解决方案4】:

您也可以自己保存f.createNewFile 并使用File.createTempFile(imageFileName, ".jpg", storageDir)

所以你的方法现在变成了

public File getFile(String url) {
    String filename = String.valueOf(url.hashCode());
    // String filename = URLEncoder.encode(url);

    return File.createTempFile(filename, ".jpg", cacheDir);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多