【问题标题】:Flutter: Exception not firing when Image.file load failsFlutter:Image.file加载失败时不会触发异常
【发布时间】:2026-01-06 15:50:01
【问题描述】:

我正在尝试从设备内存中加载图像employerPic。这张照片可能不存在,所以它应该回退到头像。 Logcat 抛出这个错误:

未处理的异常:FileSystemException:无法检索长度 文件,路径= '/data/user/0/uk.co.neighbourly/app_flutter/MYjFq4FFKKiayOl03sdX.jpg' (操作系统错误:没有这样的文件或目录,errno = 2)

基本上,我已经给了颤振一个文件路径,但是该文件在这个实例中不存在。我已将整个尝试包含在 try{} 块中,因此我可以退回到异常。你可以看到我使用了 2 个例外,一个 on FileSystemException 和一个通用的 catch(error){},但是当 try 子句失败时,都不会被触发。什么!

我想要一个解决方案,或更优雅的方式来将图像回退到有保证的图像。

if(_appDocsDir != null) {
  File employerPic = _getEmployerPicFile();
  if(employerPic != null) {
    print('JOB TILE: GOT IMAGE FROM DEVICE! path: ${employerPic.path}');
    try {
      profilePic = ClipOval(
        child: Image.file(
            employerPic, width: 60, height: 60, fit: BoxFit.cover),
      );
    } on FileSystemException {
      print(LOG + 'failed to load profilePic from mem, attempting Avatar');
      profilePic = Image.asset(
          PersonUtils.getAvatarFromId[widget._job.avatar], fit: BoxFit.cover);
    } catch(error) {
      print(LOG + '!Strange! error when attempting to load employerPhoto: $error');
    };
    }
  }

【问题讨论】:

    标签: image file flutter exception


    【解决方案1】:

    您当前的解决方案应该可以工作,只是您需要重新排列代码。 获取employerPic File 对象的代码应该在 try 块中,这样当它失败时,catch 块可以运行。

    您应该将代码更新为如下所示:

    if(_appDocsDir != null) {
        try {
          File employerPic = _getEmployerPicFile();
          if(employerPic != null) {
             print('JOB TILE: GOT IMAGE FROM DEVICE! path: ${employerPic.path}');
          }
          profilePic = ClipOval(
            child: Image.file(
                employerPic, width: 60, height: 60, fit: BoxFit.cover),
          );
        } on FileSystemException {
          print(LOG + 'failed to load profilePic from mem, attempting Avatar');
          profilePic = Image.asset(
              PersonUtils.getAvatarFromId[widget._job.avatar], fit: BoxFit.cover);
        } catch(error) {
          print(LOG + '!Strange! error when attempting to load employerPhoto: $error');
        };
        
      }
    

    【讨论】:

    • 我修改了我的代码,然后尝试复制你的代码,它运行,但抛出这个:图像资源服务捕获的异常:抛出以下 FileSystemException 解析图像编解码器:无法打开文件,路径='/data/user/0/uk.co.neighbourly/app_flutter/MYjFq4FFKKiayOl03sdX.jpg'(操作系统错误:没有这样的文件或目录,errno = 2)我认为基本上异常被Image.file捕获,尽管如此我在它的代码中看不到它。哼!感谢您对维克多的关注。
    【解决方案2】:

    这个方法行不通。最后,我在build() 中设置了我可以依赖的默认头像图像,因为我必须测试它还没有分配照片。

    我试图从我的init() 方法中获取个人资料照片,我调用了这个函数:

      void initialiseLocalStorage() async {
        _appDocsDir = await getApplicationDocumentsDirectory();
    
        if (_appDocsDir != null) {
          String pathName =
          p.join(_appDocsDir.path, "${widget._job.employerId.trim()}" + ".jpg");
          var fileExists = await io.File(pathName).exists();
          if (fileExists) {
            print(LOG + 'profile photo on device! $pathName');
            setState(() {
              profilePic = ClipOval(
                  child: Image.file(
                      File(pathName), width: 60, height: 60, fit: BoxFit.cover));
            });
            return;
          }
          else {
            print(LOG + 'profile photo not on device, keep Avatar');
            return;
          }
        } else print(LOG + 'Error _appDocsDir == $_appDocsDir so can\'t load');
      }
    

    似乎做得很好。

    学习:我认为 Flutter 的图像错误处理消除了一些解决问题的方法,引导您尝试在从 init() 调用的 async 函数中进行所有计算。

    【讨论】:

      最近更新 更多