【问题标题】:Attempting to move Image File, throwing FileNotFoundException for output directory试图移动图像文件,为输出目录抛出 FileNotFoundException
【发布时间】:2018-06-10 02:05:35
【问题描述】:

我正在尝试找到一种简单的方法来获取具有已知路径和文件夹的图像,并将其移动到图库中的新文件夹。调用此方法时,bucketName 是通过从 android Images MediaStore 中查询的 bucketNames 列表中选择来提供的。

我遇到的问题是 try 块永远不会执行,无论 bucketName 最终是什么,因为在尝试启动 OutputStream 时,它说找不到文件并跳转到 catch 块。但是,我正在目标位置创建一个文件,所以我不确定它为什么这么说。我一直在寻找替代解决方案,但是这里几乎所有的建议似乎都是使用这种方法,或者 TransferFrom 或 TransferTo(这也会产生同样的问题)。

编辑:我应该注意,每次打开应用程序时我都会检查 Write_External_Storage 权限。

public void moveImage(int position, String bucketname)
{
    String oldPath = imgList.get(position).getImage_path();
    String newPath = oldPath.replace(imgList.get(position).getImage_bucket(), bucketname);

    Log.i("index", oldPath);
    Log.i("index", newPath);

    InputStream inputStream = null;
    OutputStream outputStream = null;

    try
    {
        File newFile = new File(newPath);
        if (!newFile.exists())
        {
            boolean result = newFile.mkdirs();
            Log.i("index", "file didnt exist");
        }

        Log.i("index", "file exists");
        inputStream = new FileInputStream(new File(oldPath));
        outputStream = new FileOutputStream(newFile);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = inputStream.read(buffer)) != -1)
        {
            outputStream.write(buffer, 0, read);
        }
        inputStream.close();
        inputStream = null;

        // write the output file (You have now copied the file)
        outputStream.flush();
        outputStream.close();
        outputStream = null;
        Log.i("index", "successful");
    }
    catch (IOException ex)
    {
        ex.printStackTrace();
        Log.i("index", "unsuccessful");
    }

    //String selection = MediaStore.Images.Media.DATA + "=?";
    //String[] selectionArgs = {String.valueOf(imgList.get(position).getImage_path())};
    //ctx.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);

    imgList.remove(position);

    //Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    //intent.setData(Uri.fromFile(newFile));
    //ctx.sendBroadcast(intent);
}

这是我得到的堆栈跟踪 - 据说 newFile 存在,打印文件的新旧路径

I/index: /storage/emulated/0/Download/retrowave_80_s_bg_by_rafael_de_jongh-d9wsq5j.png
I/index: /storage/emulated/0/Camera/retrowave_80_s_bg_by_rafael_de_jongh-d9wsq5j.png
I/index: file exists
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Camera/retrowave_80_s_bg_by_rafael_de_jongh-d9wsq5j.png (Is a directory)
W/System.err:     at java.io.FileOutputStream.open(Native Method)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
W/System.err:     at com.example.kyler.bugout.MediaServer.moveImage(MediaServer.java:255)
W/System.err:     at com.example.kyler.bugout.MainActivity$4.onBucketClick(MainActivity.java:383)
W/System.err:     at com.example.kyler.bugout.MoveImageDialogFragment$1.onClick(MoveImageDialogFragment.java:44)
W/System.err:     at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1119)
W/System.err:     at android.widget.AdapterView.performItemClick(AdapterView.java:310)
W/System.err:     at android.widget.AbsListView.performItemClick(AbsListView.java:1155)
W/System.err:     at android.widget.AbsListView$PerformClick.run(AbsListView.java:3126)
W/System.err:     at android.widget.AbsListView$3.run(AbsListView.java:4041)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err:     at android.os.Looper.loop(Looper.java:154)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6077)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
I/index: unsuccessful

【问题讨论】:

  • and move it to a new folder in the gallery. 。一点都不。您正在将文件复制到文件系统。它与您设备上的图库或照片应用无关。
  • @greenapps 你有什么更好的方法推荐吗?在实施您的解决方案并取消注释让 MediaStore 扫描新文件的那部分代码后,它确实会创建一个新文件夹并将图像复制到其中......但是它也会创建该文件夹,无论是否与同名已经存在。
  • 不可能。那么你会有两个同名的文件夹!?不可能的。请在额外的代码块中显示您的代码。
  • @greenapps 两个具有相同名称的文件夹,一个缺少 DCIM 路径,但由于我设置新路径的方式。我已经修好了,非常感谢!

标签: java android file io directory


【解决方案1】:
    if (!newFile.exists())
    {
        boolean result = newFile.mkdirs();
        Log.i("index", "file didnt exist");
    }

这将创建一个目录retrowave_80_s_bg_by_rafael_de_jongh-d9wsq5j.png(实际上在您的例外中提到了该目录)。您应该将块更改为

    if (!newFile.exists())
    {
        boolean result = newFile.getParentFile().mkdirs();
        Log.i("index", "file didnt exist");
    }

【讨论】:

  • 我有一个无法解决的方法。我应该使用类似 new File(newFile.getParent()).mkdirs(); 的东西吗?我也没有得到“文件不存在”的日志,所以这个代码永远不会被调用
  • if (!newFile.exists())。那应该是if (!newFile.getParentFile().exists()) if (!newFile.getParentFile.mkdirs()) return;
  • @KyleR 我修好了。应该是getParentFile
  • @greenapps 你可能是对的,但如果文件已经存在,它也可能是正确的
  • 没有。因为如果文件不存在,那么目录仍然可以存在。然后不应该调用 mkdirs()。
猜你喜欢
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 2012-06-19
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多