Flutter Android: OS Error: File exists, Errno = 17

206 阅读1分钟

PathExistsException (PathExistsException: Cannot open file, OS Error: File exists, Errno = 17)

Errno 17 在 errno.h 中的定义是 EEXIST: File Exists 文件已经存在。

我在 File.writeAsString() 时碰到了这个错误,虽然它说文件存在所以无法打开,但实际上这个文件大概率是不存在的。就算我使用 if (!await file.exist()) 包裹 write 操作也仍然会遇到这个问题。后来我发现这个问题诡异的点在于,问题只会出现在你非第一次尝试操作这个文件的时候,当你用了一个之前没有用过的 path 那么你就不会遇到这个错误,这也成了 StackOverflow 上一个高赞但抽象的回答的解决办法:

/// I know that it's not so elegant, but it works.
String filePath = _localPath + "/" + fileName + Uuid().v4() + "." + extension;

当然这个办法是不推荐使用的。这个错误其实和文件是不是存在没什么关系,而是 APP 权限有问题。在 Android 11,API Level 30 以后读写的权限从 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 变成了 MANAGE_EXTERNAL_STORAGE,我们只需要申请这个更新后的权限就可以了。只是让人无语的是当权限不正常的时候出现的状况是操作时而成功时而失败而不是常失败让我之前还以为是自己的代码有问题。

下面是正常的解决办法:

第一步:在 AndroidManifest.xml 中声明以下权限

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

第二步:在 Flutter 中申请这个权限(以 permission_handler 为例)

await Permission.manageExternalStorage.request();