-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Files cannot be deleted if network exceptions are thrown #1920
Comments
与 dio 貌似没有任何关系,需要你自己维护 stream 的处理? |
Stream<List> openRead([int? start, int? end]); 方法,返回的是Stream<List>,将其作为参数传给dio了,dio会调用listen()来读数据,StreamSubscription listen(void onData(T event)?, {Function? onError, void onDone()?, bool? cancelOnError});,所以遇到错误的时候需要调用StreamSubscription的cancel方法关闭流。 |
我们的代码中没有任何地方对入参 Stream 进行订阅,传入的 Stream 均由 HttpRequest 进行处理。 |
可以先行确认是否有改善 |
我通过在上传期间手动断开WiFi网络来模拟SocketException: Write failed (OS Error: 你的主机中的软件中止了一个已建立的连接。,errno = 10053),但是不知道为什么没有catch到SocketException异常。 |
不需要通过操作物理设备模拟,理论上只需要延迟调用 throw 即可。 |
在哪个位置调用throw呢? |
request 开始之后,delay 一个 throw。 |
拉主分支的代码调试呀… |
问题是否依旧存在?如存在是否可以提供可以直接复现的最小demo? |
我明天用主分支测试一下 |
我试了dio: ^5.3.3,问题仍然存在,只在Windows才会遇到。 |
depedencies:
dio:
git:
url: https://github.com/cfug/dio
path: dio |
遇到依赖冲突了,不知道该如何解决...
|
提供可以直接复现的最小demo,此处不再做无关回复。 |
我不知道该如何模拟上传接口。 |
与 dio 无关,等待上游修复。 |
目前看來這應該是最簡潔的方法,缺點就是要等 StreamSubscription 自己取消 這裡有另一種可以馬上釋放 file handle 的解法,更可控但複雜度高不少,其實就是把 const fileName = "some/file/path";
final file = File(fileName);
final fileStream = file.openRead();
final fileReadController = StreamController<List<int>>();
final fileReadSubscription = fileStream.listen(
fileReadController.add,
onError: fileReadController.addError,
onDone: () => fileReadController.close()
);
final dio = Dio();
try {
await dio.post(
"https://httpbun.com/post",
data: fileReadController.stream
);
} catch (_) {
await fileReadSubscription.cancel();
await file.delete();
} |
Package
dio
Version
5.3.0
Output of
flutter doctor -v
No response
Dart Version
3.10.6
Steps to Reproduce
1.在Windows平台,使用dio上传文件
dio.requestUri(uri, data: file.openRead())
2.当遇到网络错误导致上传失败
Bad state: DioException [unknown]: null
Error: SocketException: Write failed (OS Error: 你的主机中的软件中止了一个已建立的连接。
, errno = 10053), address = private-xxx.cos.ap-guangzhou.myqcloud.com, port = 51980
3.此时想要删除该文件会提示以下错误
PathAccessException: Cannot delete file, path = 'C:\Users\6\AppData\Roaming\xxx\xxx.jpg' (OS Error: 另一个程序正在使用此文件,进程无法访问。
, errno = 32)
4.由于file.openRead() 创建的stream没有done或被cancel,仍然占用着该文件,因此无法删除文件
Expected Result
当遇到网络错误导致上传失败后,需要调用StreamSubscription的cancel方法,关闭流。
Actual Result
由于file.openRead() 创建的stream没有done或被cancel,仍然占用着该文件,因此无法删除文件
The text was updated successfully, but these errors were encountered: