A cross-platform defragmenter for .bin ROM / firmware images on SD cards & removable media
A cross-platform Avalonia desktop app that finds .bin
ROM/firmware images on a removable card and defragments the ones that are split
across the disk, so hardware that reads files by raw sector stays happy.
Defraginator looks for .bin files whose size is exactly one of:
| Size | Bytes |
|---|---|
| 256 KB | 262,144 |
| 512 KB | 524,288 |
| 1024 KB | 1,048,576 |
| 2048 KB | 2,097,152 |
Each target size can be toggled on/off before scanning.
- Drive detection — enumerates mounted volumes and keeps the ones that look
like removable media (Windows
Removable/non-system fixed drives;/media,/run/media,/mnt,/Volumeson Unix). - Scan — recursively finds
.binfiles matching the selected sizes and reads each file's physical cluster layout. - Defrag — for fragmented files, finds a contiguous run of free clusters and relocates the file into it.
The heavy lifting is isolated behind IFragmentationService, with a
platform-specific implementation selected at runtime by
FragmentationServiceFactory:
| Platform | Detection | Defragmentation |
|---|---|---|
Windows (WindowsFragmentationService) |
FSCTL_GET_RETRIEVAL_POINTERS |
In-place cluster move: FSCTL_GET_VOLUME_BITMAP to find contiguous free space + FSCTL_MOVE_FILE to relocate |
Linux (LinuxFragmentationService) |
FIEMAP ioctl (FIBMAP fallback for filesystems without FIEMAP) |
Safe verify-after-rewrite |
macOS (MacFragmentationService) |
F_LOG2PHYS_EXT fcntl |
Safe verify-after-rewrite |
| other | — | reports unsupported |
In-place move (Windows) relocates the file's clusters directly, the same way the OS defragmenter does.
Verify-after-rewrite (Linux/macOS) — FAT/exFAT have no per-file defrag syscall,
so the file is rewritten into freshly allocated space and the result is then
measured with the platform's extent API. Success is only reported once the file
is confirmed to occupy a single physical extent; if the free space is too
fragmented to place it contiguously, the original is restored and failure is
reported. The file's data is always present on disk during the operation, so an
interruption never loses it (see CopyRewriteDefragmenter).
- Windows — moving clusters opens the raw volume handle, which needs
administrator rights, so the build requests elevation (see
app.manifest). Detection works without elevation. - Linux — FIEMAP detection and the rewrite defrag run as a normal user. Only the FIBMAP fallback (for filesystems lacking FIEMAP) needs root.
- macOS — detection and defrag run as a normal user.
- .NET 10 SDK
Run from the repository root (the solution lives here):
dotnet restore
dotnet build -c Release
dotnet run --project src/Defraginator -c ReleaseDefraginator.sln Solution (root)
src/Defraginator/ Application project
Models/ RemovableDrive, BinFile, FileExtent, TargetSize
Services/ DriveDetector, BinFileScanner, IFragmentationService + factory
Windows / Linux / macOS impls, CopyRewriteDefragmenter,
Native + Unix interop
Converters/ FileState -> brush / text for the results grid
ViewModels/ MainWindowViewModel (all app logic + commands)
Views/ MainWindow.axaml (drive picker, results DataGrid, actions)
tools/ New-FragmentedTestFiles.ps1 (create fragmented test files)
- On Windows, defrag moves live filesystem clusters; the OS keeps the file
consistent during
FSCTL_MOVE_FILE. On Linux/macOS the file is rewritten with a full backup copy present on disk throughout. Either way, do not remove the card while a defrag is in progress. - Success is only reported after physical contiguity is verified, so a "Defragmented" result means the file really is a single extent.
- The tool only ever touches
.binfiles that match a selected target size.
Any per-file defrag (on every OS, including the Windows in-place move) needs a single contiguous free gap at least as large as the file. If a nearly-full card has its free space shattered into tiny pieces, a fragmented file simply cannot be made contiguous in place until space is freed or other files are relocated.
To make this visible, Defraginator reports free space for the selected drive and, on Windows, the largest contiguous free block (read from the volume bitmap). During a scan, any fragmented file bigger than that block is flagged with a ⚠ warning so you know a defrag is unlikely to succeed before you try. On Linux/macOS the largest-block figure isn't cheaply available, so it is shown as "unknown"; the defrag itself still fails safely and restores the original if it can't place the file contiguously.

