Flutter桌面端使用filepicker_windows选择文件后保存至磁盘报错的解决求助
解决方法:修正本地文件复制的逻辑
你遇到的NoSuchMethodError核心原因很明确:你把文件路径的字符串(result.path)传给了saveImage方法,但代码里错误地试图调用bodyBytes属性——这个属性根本不属于字符串类型,而是像Uint8List或者网络请求响应这类对象才会有的。
既然你已经通过文件选择器拿到了本地文件的路径,直接通过File类读取原文件的字节,再写入目标位置就可以了,不需要用bodyBytes。
具体修改步骤:
调整
saveImage方法的参数和逻辑:- 明确接收源文件的路径字符串,替换模糊的
imageData参数 - 先读取源文件的字节数据,再写入目标文件
- 明确接收源文件的路径字符串,替换模糊的
完善异步调用逻辑:
- 给
saveImage加上Future<void>返回类型,调用时添加await,确保保存完成后再输出成功提示
- 给
修改后的完整代码:
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:filepicker_windows/filepicker_windows.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { Future<String> getPicturesPath() async { Directory docDir = await getApplicationDocumentsDirectory(); var pathList = docDir.path.split('\\'); pathList[pathList.length - 1] = 'Pictures'; var picturePath = pathList.join('\\'); print(picturePath); return picturePath; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("File Management"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( 'Testing', style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: () async { final file = OpenFilePicker() ..filterSpecification = {'All Files': '*.*'} ..defaultFilterIndex = 0 ..defaultExtension = 'doc' ..title = 'Select a document'; final result = file.getFile(); if (result != null) { print(result.path); // 调用修改后的saveImage方法,添加await确保异步完成 await saveImage(result.path, 'ik.jpg'); print("Saved"); } }, tooltip: 'Increment', child: Icon(Icons.add), ), ); } // 修改后的saveImage方法,支持异步等待 Future<void> saveImage(String sourceFilePath, String imageName) async { var picturesPath = await getPicturesPath(); // 构建目标文件路径 var targetFilePath = join(picturesPath, 'theta_images', imageName); // 确保目标目录存在 await Directory(dirname(targetFilePath)).create(recursive: true); // 直接调用系统文件复制,比读写字节更高效(尤其适合大文件) await File(sourceFilePath).copy(targetFilePath); } }
额外优化说明:
我把文件复制逻辑改成了File.copy()方法,这个写法比手动读写字节更简洁高效,尤其是处理大文件时,它会直接调用系统底层的文件复制操作,避免把整个文件加载到内存中,性能更好。
内容的提问来源于stack exchange,提问作者noble
相关产品推荐
相关产品推荐

