[{"data":1,"prerenderedAt":27},["ShallowReactive",2],{"articolo-salvare-e-condividere-file-in-flutter-con-path-provider-e-file-system":3,"comments-article-salvare-e-condividere-file-in-flutter-con-path-provider-e-file-system":26},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"cover_remote_url":10,"cover_credit":11,"video_url":15,"status":16,"published_at":17,"meta_title":18,"meta_description":19,"category":20,"author":24},71,"Salvare e condividere file in Flutter con path_provider e file system","salvare-e-condividere-file-in-flutter-con-path-provider-e-file-system","Impara a gestire il file system in Flutter: individuare le directory corrette, scrivere e leggere file, gestire cache e documenti persistenti con path_provider in modo cross-platform.","## Perché gestire i file nel file system\n\nMolte app hanno bisogno di scrivere dati direttamente su disco: esportare report PDF, salvare immagini generate, mettere in cache download temporanei o memorizzare configurazioni complesse. Mentre `shared_preferences` va bene per piccole chiavi-valore e i database come Isar o Drift per dati strutturati, spesso serve accedere direttamente al **file system**.\n\nIl problema è che ogni piattaforma organizza le cartelle in modo diverso: su Android non puoi scrivere ovunque, su iOS le app sono sandboxate e su desktop le convenzioni cambiano ancora. Il pacchetto ufficiale [`path_provider`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fpath_provider) risolve questo problema esponendo le directory corrette in modo cross-platform.\n\n## Installazione\n\nAggiungi le dipendenze al `pubspec.yaml`:\n\n```yaml\ndependencies:\n  path_provider: ^2.1.4\n  path: ^1.9.0\n```\n\nIl pacchetto `path` non è obbligatorio ma è utilissimo per costruire percorsi in modo sicuro con `join`, evitando errori con i separatori.\n\n## Le directory principali\n\n`path_provider` espone diverse cartelle, ognuna con uno scopo preciso:\n\n- **`getApplicationDocumentsDirectory()`**: file persistenti dell'utente, non cancellati dal sistema. Ideale per dati che devono sopravvivere.\n- **`getTemporaryDirectory()`**: cache temporanea, il sistema può svuotarla in qualsiasi momento.\n- **`getApplicationSupportDirectory()`**: file di supporto non visibili all'utente.\n- **`getApplicationCacheDirectory()`**: cache dedicata (disponibile dalla 2.1.0).\n- **`getExternalStorageDirectory()`**: solo Android, memoria esterna dell'app.\n\n```dart\nimport 'package:path_provider\u002Fpath_provider.dart';\nimport 'package:path\u002Fpath.dart' as p;\nimport 'dart:io';\n\nFuture\u003CFile> _localFile(String name) async {\n  final dir = await getApplicationDocumentsDirectory();\n  return File(p.join(dir.path, name));\n}\n```\n\n## Scrivere e leggere file di testo\n\nUna volta ottenuto l'oggetto `File`, puoi usare le API standard di `dart:io`:\n\n```dart\nFuture\u003Cvoid> saveNote(String content) async {\n  final file = await _localFile('note.txt');\n  await file.writeAsString(content);\n}\n\nFuture\u003CString> readNote() async {\n  try {\n    final file = await _localFile('note.txt');\n    return await file.readAsString();\n  } on FileSystemException {\n    return '';\n  }\n}\n```\n\nGestire l'eccezione `FileSystemException` è importante: alla prima esecuzione il file potrebbe non esistere ancora.\n\n## Lavorare con dati binari\n\nPer immagini o PDF si usano i byte grezzi tramite `Uint8List`:\n\n```dart\nimport 'dart:typed_data';\n\nFuture\u003CFile> saveBytes(String name, Uint8List bytes) async {\n  final dir = await getApplicationDocumentsDirectory();\n  final file = File(p.join(dir.path, name));\n  return file.writeAsBytes(bytes);\n}\n\nFuture\u003CUint8List?> readBytes(String name) async {\n  final dir = await getApplicationDocumentsDirectory();\n  final file = File(p.join(dir.path, name));\n  if (await file.exists()) {\n    return file.readAsBytes();\n  }\n  return null;\n}\n```\n\n## Gestire la cache in modo pulito\n\nLa cartella temporanea è perfetta per download che possono essere rigenerati. Ecco un esempio che scarica e mette in cache un file, riutilizzandolo se già presente:\n\n```dart\nFuture\u003CFile> cachedDownload(String url, String fileName) async {\n  final tempDir = await getTemporaryDirectory();\n  final file = File(p.join(tempDir.path, fileName));\n\n  if (await file.exists()) {\n    return file; \u002F\u002F già in cache\n  }\n\n  final response = await HttpClient().getUrl(Uri.parse(url))\n      .then((req) => req.close());\n  final bytes = await consolidateHttpClientResponseBytes(response);\n  await file.writeAsBytes(bytes);\n  return file;\n}\n```\n\n### Svuotare la cache\n\nÈ buona pratica offrire all'utente un modo per liberare spazio:\n\n```dart\nFuture\u003Cvoid> clearCache() async {\n  final tempDir = await getTemporaryDirectory();\n  if (await tempDir.exists()) {\n    await tempDir.delete(recursive: true);\n  }\n}\n```\n\n## Elencare i file di una cartella\n\nPer mostrare all'utente i file salvati puoi iterare sul contenuto di una directory:\n\n```dart\nFuture\u003CList\u003CFile>> listSavedFiles() async {\n  final dir = await getApplicationDocumentsDirectory();\n  final entities = dir.listSync();\n  return entities.whereType\u003CFile>().toList();\n}\n```\n\nUsa `listSync()` con cautela su cartelle molto grandi: in quei casi preferisci lo stream asincrono `dir.list()`.\n\n## Best practice\n\n- **Non salvare percorsi assoluti** in un database: su iOS il path della sandbox può cambiare tra un aggiornamento e l'altro. Memorizza solo il nome del file e ricostruisci il percorso a runtime.\n- **Scegli la directory giusta**: usa i documenti per dati importanti e la cache per contenuti rigenerabili, così eviti di occupare spazio non liberabile dal sistema.\n- **Gestisci sempre le eccezioni** di I\u002FO: dischi pieni e permessi mancanti sono scenari reali.\n- **Sposta operazioni pesanti in un isolate** con `compute` se scrivi o leggi file di grandi dimensioni, per non bloccare la UI.\n- **Su Flutter Web** `path_provider` non funziona: usa soluzioni basate su `IndexedDB` o su download del browser.\n\n## Conclusione\n\nLa gestione del file system in Flutter è più semplice di quanto sembri grazie a `path_provider`, che astrae le differenze tra le piattaforme. Combinando le directory corrette con le API di `dart:io` e il pacchetto `path` puoi costruire funzionalità robuste di persistenza, export e caching, mantenendo il codice pulito e portabile.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002F5c118e80-7601-425c-9e84-16b07c787ff3.jpg","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1773266110372-44e7b9bad188?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w5NzA2NTJ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3ODczMTU4Njl8&ixlib=rb-4.1.0&q=80&w=1080",{"name":12,"author_url":13,"photo_url":14},"Daniel Brzdęk","https:\u002F\u002Funsplash.com\u002F@format_","https:\u002F\u002Funsplash.com\u002Fphotos\u002Fvintage-wooden-card-catalog-drawers-with-labels-kAQo6CJCPN4",null,"published","2026-08-19T04:00:38+00:00","File system in Flutter con path_provider: guida pratica","Come salvare, leggere e gestire file in Flutter con path_provider: directory corrette, cache, dati binari e best practice cross-platform.",{"id":21,"name":22,"slug":23},1,"Guide","guide",{"id":21,"name":25},"Flutter Bot",[],1789205512285]