You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter iOS端偶现PathNotFoundException:无法获取文件长度问题求助

iPhone 草稿上传文件偶发 PathNotFoundException 问题排查与解决

核心原因分析

  • iOS临时文件路径的时效性:直接上传时,系统通过文件选择器授予APP的是临时访问权限,返回的路径指向沙盒内的临时文件。当APP被后台回收、系统清理临时目录,或者间隔时间过长后,该路径对应的文件会被系统删除,导致读取时触发路径不存在异常。
  • SQLite存储内容错误:如果存入草稿的是文件的原始临时路径,而非持久化的文件标识,就会出现路径失效的偶发问题——iOS不保证临时路径的长期有效性。
  • 偶发触发场景:常见于APP重启后、后台驻留过久被系统回收后,或者系统自动清理临时文件目录时,此时草稿中的旧路径已无法指向有效文件。

可行解决方案

1. 存储文件的持久化书签(Bookmark Data)

不要直接存储文件路径,而是将选中文件的NSURL转换为书签数据存入SQLite。书签数据包含了文件的持久化访问权限,即使APP重启也能恢复有效URL并获取访问权限:

// 获取文件书签数据
NSData *bookmarkData = [selectedURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                             includingResourceValuesForKeys:nil
                                              relativeToURL:nil
                                                      error:nil];
// 将bookmarkData存入SQLite(需转为可存储的格式,比如Base64字符串)

// 恢复URL并获取访问权限
NSData *storedBookmarkData = // 从SQLite读取的书签数据
BOOL isStale;
NSURL *restoredURL = [NSURL URLByResolvingBookmarkData:storedBookmarkData
                                               options:NSURLBookmarkResolutionWithSecurityScope
                                         relativeToURL:nil
                                   bookmarkDataIsStale:&isStale
                                                 error:nil];
if (restoredURL) {
    [restoredURL startAccessingSecurityScopedResource];
    // 执行文件上传操作
    [restoredURL stopAccessingSecurityScopedResource];
}

2. 将文件复制到APP沙盒存储

选中文件后,先把文件复制到APP的Documents或Library目录,再将沙盒内的路径存入草稿。沙盒内的文件不会被系统自动清理,路径长期有效:

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *targetFilePath = [documentsPath stringByAppendingPathComponent:[selectedURL lastPathComponent]];
NSURL *targetURL = [NSURL fileURLWithPath:targetFilePath];

// 复制文件到沙盒
NSError *error;
if ([fileManager copyItemAtURL:selectedURL toURL:targetURL error:&error]) {
    // 将targetFilePath存入SQLite作为草稿路径
} else {
    // 处理复制失败逻辑
}

3. 上传前校验文件有效性

从草稿读取路径后,先检查文件是否存在,若不存在则提示用户重新选择文件,避免抛出异常:

NSString *storedPath = // 从SQLite读取的文件路径
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storedPath]) {
    // 提示用户:文件已失效,请重新选择
    return;
}
// 执行上传操作

内容的提问来源于stack exchange,提问作者M.A.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:52:38