skip to content

A Flutter app saves PDF lecture notes for offline reading; which path_provider directory should hold them, and what may purge or back them up?

level: middleimportance: should knowfreq 40%

answer

  1. kept on purpose versus re-downloadable
  2. the OS may clear caches under low storage
  3. documents and support get backed up
  4. Android Auto Backup skips the cache dir
  5. clear cache versus clear storage

basics

~20 s

Notes the user chose to keep belong in documents or support, because the OS may delete cache contents under storage pressure. Those persistent directories are backed up by default on iOS and by Android Auto Backup, so large re-downloadable PDFs inflate backups.

solid answer

~50 s

I split files by who expects them to survive. A PDF the user tapped "save offline" on goes into `getApplicationSupportDirectory()` (or documents if users should think of it as their file), because the cache directory from `getApplicationCacheDirectory()` can be cleared by the system when storage runs low, or by the user choosing "clear cache" in Android settings. Rebuildable data such as previews goes in the cache. The trade-off is backups: on iOS, Documents and Application Support are included in device backups while Caches is not, and Android Auto Backup covers internal files but excludes the cache directory. Large PDFs that can be downloaded again are therefore a backup cost, so I keep them out of backups where the platform allows, and I store only relative paths plus a record of what was downloaded so the app can re-fetch anything that disappears.

code

dart · 21 lines
dart
import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

/// Returns a path relative to the support directory, safe to persist.
Future<String> saveOfflineNote(String noteId, Stream<List<int>> bytes) async {
  final tmp = await getTemporaryDirectory();
  final partial = File(p.join(tmp.path, '$noteId.part'));
  final sink = partial.openWrite();
  await sink.addStream(bytes);
  await sink.close();

  final support = await getApplicationSupportDirectory();
  final relative = p.join('notes', '$noteId.pdf');
  final target = File(p.join(support.path, relative));
  await target.parent.create(recursive: true);
  await partial.copy(target.path);
  await partial.delete();
  return relative;
}

go deeper

for a junior

Recall that cache and temporary files can disappear, while documents and support survive until uninstall.

for a middle

Explain purge and backup rules per directory on iOS and Android, and why kept downloads should not live in the cache.

for a senior

Design the layout with temporary downloads, a relative-path index, re-download on loss and a clear-cache action that spares saved notes.

for a principal

Weigh offline convenience against device storage and user backup quotas, and decide how much the app should keep by default.

## The question behind the question Interviewers ask this because choosing a directory is really choosing a **lifecycle**. Every directory returned by **`path_provider`** comes with platform rules about three things: whether the system may delete its contents, whether they are included in backups, and whether the user can see them. For offline lecture notes the stakes are concrete: a student who downloaded forty PDFs before a flight must still have them when the plane takes off. ## What can remove files | Directory function | iOS | Android | |---|---|---| | `getApplicationDocumentsDirectory()` | kept until the app is deleted | kept until uninstall or "clear storage" | | `getApplicationSupportDirectory()` | kept until the app is deleted | kept until uninstall or "clear storage" | | `getApplicationCacheDirectory()` / `getTemporaryDirectory()` | `Library/Caches`: the system may purge it when storage is low | `getCacheDir()`: the system may delete files when storage is low; the user can "clear cache" | The path_provider documentation states the contract directly for the temporary directory: files there "may be cleared at any time". That makes the cache the wrong home for anything the user explicitly saved. Uninstalling the app removes all four on both platforms. ## What gets backed up Backups are the other half of the trade-off. - **iOS** includes the app's `Documents` and `Library/Application Support` contents in iCloud and computer backups by default, and leaves `Library/Caches` out. Hundreds of megabytes of PDFs in Documents therefore count against the user's iCloud storage and slow restores. - **Android Auto Backup** includes the app's internal files, databases and preferences by default and excludes the cache directory. Its per-app quota is limited, and apps can include or exclude paths with backup rules in the manifest. Neither platform lets `path_provider` itself change backup behaviour; marking a file as excluded from iOS backup, or writing Android backup rules, is native configuration. ## A layout for the lecture-notes app 1. **Downloaded PDFs**: `getApplicationSupportDirectory()/notes/<course>/<id>.pdf`. Persistent and private. If the product wants users to see the PDFs in the iOS Files app, use documents instead and enable file sharing in `Info.plist`. 2. **Index of what is downloaded**: a small database or JSON file in support, with **relative** paths and sizes. 3. **Previews and page thumbnails**: the cache directory; rebuilt on demand. 4. **In-progress downloads**: the temporary directory, then renamed into place when complete, so a purge or crash never corrupts a finished note. ## A decision checklist per file 1. **Did the user ask to keep it?** Then a persistent directory: support, or documents if they should see it as their file. 2. **Can the app rebuild or re-download it cheaply?** Then the cache, and accept that it may vanish. 3. **Is it large and re-downloadable but still kept?** Keep it persistent, and consider excluding it from backups natively so users do not pay for it twice. 4. **Is it half-written?** Then the temporary directory until it is complete. 5. **Must another app or the user's file manager see it?** Then none of these alone: use the platform's sharing or document APIs. Answering these five questions for each file type turns a vague "where do I save files?" into a layout the whole team can follow. ## Designing for disappearance anyway Even persistent directories are not guaranteed forever: the user can clear storage on Android, reinstall, or restore a backup that skipped files. A robust app: - treats the index as the source of truth and checks that each file exists before opening it; - offers **re-download** for missing notes instead of failing; - shows how much space downloads use and lets the user remove them; - offers a **"clear cache"** action that deletes only the contents of the cache directory, never the saved notes. ## Common wrong answers - "Put them in the cache, it is meant for downloaded files": true for re-fetchable caches, wrong for files the user chose to keep. - "Documents is never backed up, so size does not matter": on iOS it is backed up by default. - "Temporary files last until the app deletes them": the system may remove them.

  • Why does the snippet copy from the temporary directory instead of renaming the file into support storage?
    On desktop the temporary directory can live on a different volume from support storage, such as a tmpfs `/tmp` on Linux, and a rename across volumes fails. Copying then deleting works everywhere. On Android and iOS both sit in the app container, so a rename is cheaper and atomic there, and some apps try `rename` first and fall back to copying.
  • On Android, what is the difference for a Flutter app between the user tapping clear cache and clear storage?
    Clear cache empties the directory returned by `getCacheDir()`, which is what path_provider's temporary and cache functions return, so previews vanish but saved notes survive. Clear storage wipes all app data, including support, documents, databases and preferences, as if the app were freshly installed.

Think of a student's desk versus the classroom's lost-and-found shelf: the notes on the desk (support and documents) stay and get photocopied into the archive (backup), while anything left on the shelf (cache) may be thrown out by the caretaker whenever space runs short.

saying these in an interview costs you the question

  • Offline downloads the user chose to keep belong in the cache directory.
  • Files in getTemporaryDirectory() persist until the app deletes them.
  • iOS never backs up the Documents directory, so its size does not matter.
  • path_provider has an option to exclude a directory from backups.
  • Android Auto Backup includes the cache directory.