Closed feimenggo closed 10 months ago
与 dio 貌似没有任何关系,需要你自己维护 stream 的处理?
与 dio 貌似没有任何关系,需要你自己维护 stream 的处理?
Stream<List
dio会调用listen()来读数据
我们的代码中没有任何地方对入参 Stream 进行订阅,传入的 Stream 均由 HttpRequest 进行处理。
最终是在这里被addStream()的,那当流还没有读完的时候,遇到网络错误了要怎么关闭流呢,是不是应该调用request.abort()方法?
是不是应该在这里遇到错误的时候,调用 request.close(); 或 request.abort(); 方法呢?
是不是应该在这里遇到错误的时候,调用 request.close(); 或 request.abort(); 方法呢?
可以先行确认是否有改善
是不是应该在这里遇到错误的时候,调用 request.close(); 或 request.abort(); 方法呢?
可以先行确认是否有改善
我通过在上传期间手动断开WiFi网络来模拟SocketException: Write failed (OS Error: 你的主机中的软件中止了一个已建立的连接。,errno = 10053),但是不知道为什么没有catch到SocketException异常。
不需要通过操作物理设备模拟,理论上只需要延迟调用 throw 即可。
在哪个位置调用throw呢?
request 开始之后,delay 一个 throw。
尝试把 io_adapter.dart#L154 改成如图后再试
怎么代码不一样,我这里是在150行呢?
拉主分支的代码调试呀…
怎么代码不一样,我这里是在150行呢?
我刚试了dio: 5.3.2,在L150位置加try,没有捕获到异常,而是直接在最开始dio.requestUri()处捕获到异常了
问题是否依旧存在?如存在是否可以提供可以直接复现的最小demo?
问题是否依旧存在?如存在是否可以提供可以直接复现的最小demo?
我明天用主分支测试一下
我试了dio: ^5.3.3,问题仍然存在,只在Windows才会遇到。 我是在上传文件的过程中,断开电脑的网络连接,然后删除这个文件,就会提示:文件正在使用,操作无法完成,因为文件已在 xx软件 中打开。
我尝试拉main分支的代码调试 报了这个错误,这是什么原因?
depedencies:
dio:
git:
url: https://github.com/cfug/dio
path: dio
遇到依赖冲突了,不知道该如何解决...
Because qcloud_cos_client 0.0.7 depends on dio ^5.3.0 and no versions of qcloud_cos_client match >0.0.7 <0.1.0, qcloud_cos_client ^0.0.7 requires dio from hosted.
So, because app depends on both dio from git and qcloud_cos_client ^0.0.7, version solving failed.
提供可以直接复现的最小demo,此处不再做无关回复。
我不知道该如何模拟上传接口。 简单来说就是使用dio上传文件到腾讯对象存储,当上传还没结束的时候,断开了电脑的网络连接,此时会提示”你的主机中的软件中止了一个已建立的连接“,此时这个文件文件流仍然被dio持有着没有释放,因此无法移动/删除文件,会提示:文件正在使用,操作无法完成,因为文件已在 xx软件 中打开。
与 dio 无关,等待上游修复。
目前看來這應該是最簡潔的方法,缺點就是要等 StreamSubscription 自己取消
這裡有另一種可以馬上釋放 file handle 的解法,更可控但複雜度高不少,其實就是把 .asBroadcastStream()
拆出來用😂
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,仍然占用着该文件,因此无法删除文件