File Storage
Scanly stores document images in app-private directories managed by AppPrivateDocumentStorageManager (data/storage/).
Image paths referenced in Room entities point to files under these directories. The database stores metadata; the filesystem stores pixels.
Per-document layout
files/documents/{documentId}/
├── raw/
│ └── page_001.jpg, page_002.jpg, … # Immutable captures
├── processed/
│ └── page_001.jpg, page_002.jpg, … # Derived corrected/filtered output
└── thumbs/
├── cover.jpg # Document cover thumbnail
└── page_001.jpg, page_002.jpg, … # Page list thumbnails
| Directory | Mutability | Purpose |
|---|---|---|
raw/ | Immutable | Original camera capture or imported image |
processed/ | Regenerated on edit | Perspective-corrected, filtered JPEG |
thumbs/ | Regenerated on edit | Small previews for lists and covers |
Design rules
- Never overwrite raw files. Edits call
reprocessPage, which reads fromraw/and writes newprocessed/andthumbs/paths. - Paths in Room are authoritative. Repositories update entity path columns after every write.
- Document root is stored in
DocumentEntity.rootDirectoryPathfor cleanup and migration.
App-private working directories
| Path | Purpose |
|---|---|
cache/library-archive/ | Restore staging workspace |
files/library-archive-journal/ | Durable restore recovery journal |
databases/scanly.db (+ -wal, -shm) | Room database |
Export cache
Ephemeral export artifacts live outside document directories:
cache/exports/{documentId}/ # Single-document PDF or ZIP
cache/exports/group_{groupId}/ # Group merged PDF or zipped PDFs
Export cache can be cleared without losing library data. It is included in storage usage reporting and wiped by clear-all-data.
User-visible exports and backups
Generated cache artifacts are copied to shared storage when the user chooses Save:
Downloads/Scanly/ # Default direct-save destination
└── backup/ # Reserved for .scanly backups
A Storage Access Framework tree selected in Settings replaces Downloads/Scanly as the base. Normal exports use the base; Scanly creates and manages its lowercase backup child. Persisted access is required, existing names receive numeric suffixes, and partial writes are removed after failure or cancellation.
.scanly is a ZIP container with a versioned manifest, entity metadata, exact raw/processed/thumbnail assets, sizes, and SHA-256 checksums. Settings, export cache, SQLite files, and previous backups are excluded.
Thumbnail cache
ThumbnailCache (core/ui/) maintains an in-memory cache of decoded thumbnails for fast list scrolling. Invalidated when:
- A page is reprocessed
- A document cover changes
- Clear-all-data runs
Capture path allocation
Before capture or import:
PageRepository.prepareCaptureorprepareReplacementCaptureallocates the nextraw/page_NNN.jpgpath.- Camera or gallery writes the raw JPEG to that path.
finalizeCaptureruns processing and writesprocessed/andthumbs/.
Image format settings
Processed JPEG output (from PageImageProcessor):
- Quality: 94
- Max dimension: 2800 px (longer edge; processing is capped at the same size, see ../processing/image-processing.md)
Storage usage reporting
GetAppStorageUsageUseCase → DefaultAppDataRepository reports:
| Category | What it measures |
|---|---|
| Documents | All files under files/documents/ |
| Export cache | All files under cache/exports/ |
| Database | scanly.db file size |
| Archive workspace | Restore staging and recovery journals |
Displayed in Settings via StorageFormatter.
Clear all data
ClearAllAppDataUseCase performs a full wipe:
database.clearAllTables()— all Room records- Delete every directory under
files/documents/ - Delete
cache/exports/ thumbnailCache.clearAll()- Delete backup/restore workspace files; completed external
.scanlybackups are kept
Destructive and irreversible. Requires user confirmation in Settings.
Related docs
- database.md — Room entities referencing these paths
- ../processing/image-processing.md — how processed files are generated
- ../processing/export.md — export cache usage