In Flutter's path_provider, how do the documents, support, temporary and cache directories differ, and what does each map to on iOS and Android?
answer
- who created the file, who may delete it
- documents: user data that cannot be recreated
- support: app files hidden from the user
- temporary and cache: purgeable
- Android getCacheDir, iOS Library/Caches
basics
~20 sDocuments holds user-generated or unrecreatable data, support holds app-private files, and temporary and cache hold re-creatable data the OS may clear. On iOS they map to Documents, Application Support and Caches; on Android to app_flutter, files and the cache dir.
solid answer
~40 s`path_provider` returns `Directory` objects for platform locations; you then use `dart:io` to read and write inside them. `getApplicationDocumentsDirectory()` is for data the user created or that cannot be recreated: `NSDocumentDirectory` on iOS, an `app_flutter` directory from `Context.getDir` on Android. `getApplicationSupportDirectory()` is for app files you do not expose to the user, such as a database: Application Support on iOS, `Context.getFilesDir()` on Android, created if missing. `getTemporaryDirectory()` and `getApplicationCacheDirectory()` are for data you can fetch or rebuild; on Android and iOS they resolve to the same directory (`getCacheDir()` and `NSCachesDirectory`), which the system may clear. All of them are app-scoped on mobile and are removed when the app is uninstalled.
code
dart · 16 linesimport 'dart:io';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
Future<File> offlineNoteFile(String courseId, String noteId) async {
final docs = await getApplicationDocumentsDirectory();
final dir = Directory(p.join(docs.path, 'notes', courseId));
await dir.create(recursive: true);
return File(p.join(dir.path, '$noteId.pdf'));
}
Future<File> thumbnailFile(String noteId) async {
final cache = await getApplicationCacheDirectory();
return File(p.join(cache.path, 'thumbs', '$noteId.png'));
}go deeper
Recall the four functions and one-line purposes: documents for user data, support for app files, temporary and cache for purgeable data.
Explain the iOS and Android mappings, including that temporary and cache coincide on mobile, and why you store relative paths.
Map each kind of file in a real feature to a directory, and plan for purging, partial downloads and backup size.
Set a storage policy across the app: which data is user-owned, which is re-creatable, and how that shapes quotas and support costs.
## What path_provider is for A Flutter app that writes files, such as a study app that saves PDF lecture notes for offline reading, first needs to know **where** it is allowed to write. Each operating system has its own sandbox layout and conventions. The **`path_provider`** plugin (2.1.x, maintained in the flutter/packages repository) hides those differences behind a few async functions that return `dart:io` `Directory` objects. Reading and writing files inside them is then ordinary `dart:io` work. The functions differ less in *where* they point than in the **contract** each directory carries: who owns the data, whether the system may delete it, and whether it is backed up. ## The four everyday directories | Function | Intended content | iOS | Android | |---|---|---|---| | `getApplicationDocumentsDirectory()` | user-generated data, or data that cannot be recreated | `NSDocumentDirectory` | `Context.getDir("flutter")`, the `app_flutter` folder | | `getApplicationSupportDirectory()` | app files not meant for the user, such as a database or config | `NSApplicationSupportDirectory`, created if missing | `Context.getFilesDir()` | | `getTemporaryDirectory()` | scratch files and caches that may vanish | `NSCachesDirectory` | `Context.getCacheDir()` | | `getApplicationCacheDirectory()` | app-specific caches | `NSCachesDirectory`, created if missing | `Context.getCacheDir()` | Two details surprise people: - On **Android and iOS, `getTemporaryDirectory()` and `getApplicationCacheDirectory()` return the same directory**. The separate cache function exists mainly because the desktop platforms have distinct cache locations. - On iOS, the "temporary" directory is `Library/Caches`, not the `tmp` folder. The plugin's documentation says files there may be cleared at any time, and that the call does not create a fresh temporary folder: you create and clean up your own files inside it. ## Choosing for the lecture-notes app 1. A PDF the user explicitly downloads to read offline is data the user asked to keep. Losing it silently would be a bug, so it belongs in **documents** or **support**, not in a cache. 2. A thumbnail rendered from the first page can be rebuilt at any time, so it belongs in the **cache** directory. 3. The app's own database of which notes are downloaded is app data, not a user document, so it belongs in **support**. 4. A half-finished download goes to **temporary** first and is moved into place only when complete, so a crash never leaves a truncated PDF where the reader expects a good one. ## Other functions in the same package - `getLibraryDirectory()` is iOS and macOS only; calling it on other platforms throws. - `getExternalStorageDirectory()`, `getExternalStorageDirectories()` and `getExternalCacheDirectories()` are Android only and return app-specific folders on shared or removable storage. - `getDownloadsDirectory()` returns a downloads location whose meaning differs by platform and may be `null`. When a directory that should exist cannot be obtained, the functions throw `MissingPlatformDirectoryException`. None of them has a web implementation. ## How the plugin reaches the platform `path_provider` is a **federated plugin**: the app depends on `path_provider`, which endorses one implementation package per platform (`path_provider_android`, `path_provider_foundation` for iOS and macOS, `path_provider_linux`, `path_provider_windows`). Recent releases of the Android and Apple implementations call platform APIs directly through JNI and FFI rather than a method channel; the Dart API you call is unchanged. That design matters in tests. A widget or unit test has no real platform, so the plugin's README recommends replacing `PathProviderPlatform.instance` with a fake rather than mocking a method channel. The package's own tests do this with a class that extends `Fake`, mixes in `MockPlatformInterfaceMixin` and implements `PathProviderPlatform`, returning paths under a temporary test folder. Code that receives its directories through a small injected service is easier still to test. ## Practical rules - Call the function each time you need a path, or cache the `Directory` for the session, but never persist an **absolute** path; the directory's location can change, for example across iOS reinstalls or restores. - Store paths **relative** to the directory you chose, and join them at runtime with `package:path`. - Keep large, re-downloadable files out of backed-up directories when you can; the next question in an interview is usually about backups.
- With path_provider on Android, why would getApplicationDocumentsDirectory() not show up in the device's Files app?On Android it returns an app-private folder created with `Context.getDir("flutter")`, inside the app's internal storage. Other apps and the user's file manager cannot see it. It is private storage despite the name "documents".
- Does path_provider's getTemporaryDirectory() give each call a fresh, empty folder?No. It returns the same app-scoped cache location every time, on iOS `Library/Caches` and on Android `getCacheDir()`. Your code creates, names and deletes its own files or subfolders inside it, and must expect the system to remove them.
saying these in an interview costs you the question
- getTemporaryDirectory() returns a new empty folder on each call.
- Anything in the cache directory stays until the app deletes it.
- getApplicationDocumentsDirectory() on Android is the shared Documents folder.
- Persisting the absolute path of a saved file is safe across updates.
- Temporary and cache directories are different folders on Android and iOS.