skip to content

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?

level: juniorimportance: must knowfreq 60%

answer

  1. who created the file, who may delete it
  2. documents: user data that cannot be recreated
  3. support: app files hidden from the user
  4. temporary and cache: purgeable
  5. Android getCacheDir, iOS Library/Caches

basics

~20 s

Documents 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 lines
dart
import '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

for a junior

Recall the four functions and one-line purposes: documents for user data, support for app files, temporary and cache for purgeable data.

for a middle

Explain the iOS and Android mappings, including that temporary and cache coincide on mobile, and why you store relative paths.

for a senior

Map each kind of file in a real feature to a directory, and plan for purging, partial downloads and backup size.

for a principal

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.