Flutter_cached_network_image: FileSystemException: Cannot delete file

Created on 11 Feb 2020  路  10Comments  路  Source: Baseflow/flutter_cached_network_image

Firebase keeps reporting issues in my app that look like this:

FileSystemException: Cannot delete file, path = '/data/user/0/<PACKAGE>/cache/libCachedImageData/6cbff3e0-301f-11ea-d72d-0335a490e7f0.png' (OS Error: No such file or directory, errno = 2)

Not really sure what causes them, I have a hard time recreating it too.

bug up for graps

Most helpful comment

The problem caused by cache_store.dart 鈥檚 _cleanupCache (in flutter_cache_manager-1.2.2)

````
Future _cleanupCache() async {
final toRemove = [];
final provider = await _cacheInfoRepository;

final overCapacity = await provider.getObjectsOverCapacity(_capacity);
for (final cacheObject in overCapacity) {
  unawaited(_removeCachedFile(cacheObject, toRemove));
}

final oldObjects = await provider.getOldObjects(_maxAge);
for (final cacheObject in oldObjects) {
  unawaited(_removeCachedFile(cacheObject, toRemove));
}

await provider.deleteAll(toRemove);

}
``` overCapactiyandoldObjectsare both lists ofCacheObjectto be deleted. In some cases, one file may be deleted twice, and the_removeCachedFile` is an asynchronous function, resulting in a double-delete crash

Future<void> _removeCachedFile(CacheObject cacheObject, List<int> toRemove) async { // ... more code final file = (await fileDir).childFile(cacheObject.relativePath); if (await file.exists()) { unawaited(file.delete()); } }

All 10 comments

I have the same problem

I think that it is related with how flutter_cache_manager manages the cache:

https://pub.dev/packages/flutter_cache_manager#-changelog-tab-

Perhaps it is a good idea to try to upgrade flutter_cache_manager to last version.

I'm having this issue too. My guess is that there is no guarantee that the cache is not cleared by the system. But it is causing a great deal of noise in Crashlytics since every error is unique with the image filename.

That's strange.. The only 2 places where a file is deleted have checks for existence:

    var file = new File(p.join(await filePath, cacheObject.relativePath));
    if (await file.exists()) {
      file.delete();
    }

Which version of cached_network_image are you using?

The version I am using is cached_network_image: ^2.0.0.

i have the same problem right now, and using cached_network_image 2.0.0

problem persists in 2.1.0+1

Same problem, both Android and iOS.

The problem caused by cache_store.dart 鈥檚 _cleanupCache (in flutter_cache_manager-1.2.2)

````
Future _cleanupCache() async {
final toRemove = [];
final provider = await _cacheInfoRepository;

final overCapacity = await provider.getObjectsOverCapacity(_capacity);
for (final cacheObject in overCapacity) {
  unawaited(_removeCachedFile(cacheObject, toRemove));
}

final oldObjects = await provider.getOldObjects(_maxAge);
for (final cacheObject in oldObjects) {
  unawaited(_removeCachedFile(cacheObject, toRemove));
}

await provider.deleteAll(toRemove);

}
``` overCapactiyandoldObjectsare both lists ofCacheObjectto be deleted. In some cases, one file may be deleted twice, and the_removeCachedFile` is an asynchronous function, resulting in a double-delete crash

Future<void> _removeCachedFile(CacheObject cacheObject, List<int> toRemove) async { // ... more code final file = (await fileDir).childFile(cacheObject.relativePath); if (await file.exists()) { unawaited(file.delete()); } }

Nice catch @williamtank.

I guess it should be enough to do the removal inside the if (or revert the if)

Current:

  Future<void> _removeCachedFile(
      CacheObject cacheObject, List<int> toRemove) async {
    if (!toRemove.contains(cacheObject.id)) {
      toRemove.add(cacheObject.id);
      if (_memCache.containsKey(cacheObject.url)) {
        _memCache.remove(cacheObject.url);
      }
      if (_futureCache.containsKey(cacheObject.url)) {
        unawaited(_futureCache.remove(cacheObject.url));
      }
    }
    final file = (await fileDir).childFile(cacheObject.relativePath);
    if (await file.exists()) {
      unawaited(file.delete());
    }
  }

Proposed:

  Future<void> _removeCachedFile(
      CacheObject cacheObject, List<int> toRemove) async {
    if (!toRemove.contains(cacheObject.id)) {
      return;
    }
    toRemove.add(cacheObject.id);
    if (_memCache.containsKey(cacheObject.url)) {
      _memCache.remove(cacheObject.url);
    }
    if (_futureCache.containsKey(cacheObject.url)) {
      unawaited(_futureCache.remove(cacheObject.url));
    }
    final file = (await fileDir).childFile(cacheObject.relativePath);
    if (await file.exists()) {
      unawaited(file.delete());
    }
  }

The async only goes async at the first await.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

port3000 picture port3000  路  5Comments

BerndWessels picture BerndWessels  路  6Comments

yossefEl picture yossefEl  路  4Comments

srburton picture srburton  路  6Comments

chow2324 picture chow2324  路  4Comments