sized_file 1.3.2
sized_file: ^1.3.2 copied to clipboard
A lightweight and intuitive Dart package for file size conversions and formatting them for human-readable display. Convert between bytes, kilobytes, megabytes, gigabytes, and terabytes using construct [...]
Sized File
A lightweight and intuitive Dart package for file size conversions and formatting them for human-readable display. Convert between bytes, kilobytes, megabytes, gigabytes, and terabytes using constructors or convenient extension methods. Supports arithmetic operations, comparisons, and localization for a complete file size handling solution.
Features #
- 🔄 Easy Conversions: Convert between different size units (B, KB, MB, GB, TB)
- ✨ Extension Methods: Create file sizes using intuitive syntax like
5.mbor1.gb - 🎯 Mixed Units Support: Create file sizes from multiple units with
SizedFile.units - 📊 Smart Formatting: Automatically format sizes with appropriate units
- 🎨 Customizable: Configure fraction digits and custom unit postfixes
- 🌍 Localization Support: Set custom postfix generators for internationalization
- ⚡ Lightweight: Zero dependencies, pure Dart implementation
- 🧮 Precise Calculations: Uses 1024 as the divider (binary) for accurate storage size calculations
- ⚖️ Comparison Support: Full equality and comparison operators (
==,<,>,<=,>=) - 🗂️ Collection Ready: Works seamlessly with
Set,Map, and sorting operations - ➕ Arithmetic Operations: Add, subtract, multiply, and divide file sizes
- 🔢 Mathematical Functions: Built-in
min,max,sum, andaveragehelpers - 📐 Comparable Interface: Implements
Comparable<SizedFile>for natural sorting
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
sized_file: ^1.3.2
Then run:
dart pub get
Or with Flutter:
flutter pub get
Usage #
Basic Usage #
Creating SizedFile Instances
You can create a SizedFile instance from any unit:
import 'package:sized_file/sized_file.dart';
// From bytes
final size1 = SizedFile.b(1024);
// From kilobytes
final size2 = SizedFile.kb(1.5);
// From megabytes
final size3 = SizedFile.mb(100);
// From gigabytes
final size4 = SizedFile.gb(2.5);
// From terabytes
final size5 = SizedFile.tb(1);
// From mixed units (combine multiple units)
final size6 = SizedFile.units(
gb: 2,
mb: 500,
kb: 256,
);
Creating from Mixed Units
When you need to combine multiple units into a single file size, use the SizedFile.units factory constructor. This is particularly useful for expressing sizes like "2 GB + 500 MB + 256 KB":
// Video file: 2 GB + 500 MB + 256 KB
final videoFile = SizedFile.units(
gb: 2,
mb: 500,
kb: 256,
);
print(videoFile.format()); // "2.49 GB"
print(videoFile.inBytes); // 2672033792
// Database backup: 10 MB + 1024 bytes
final backup = SizedFile.units(
mb: 10,
b: 1024,
);
print(backup.format()); // "10.00 MB"
// Media project: 1 GB + 750 MB + 512 KB + 256 bytes
final project = SizedFile.units(
gb: 1,
mb: 750,
kb: 512,
b: 256,
);
print(project.format()); // "1.73 GB"
// All parameters are optional and default to 0
final onlyMB = SizedFile.units(mb: 500);
print(onlyMB == SizedFile.mb(500)); // true
Accessing Different Units
Once created, you can access the size in any unit:
final fileSize = SizedFile.mb(5);
print(fileSize.inBytes); // 5242880
print(fileSize.inKB); // 5120.0
print(fileSize.inMB); // 5.0
print(fileSize.inGB); // 0.0048828125
print(fileSize.inTB); // 0.00000476837158203125
Formatting #
Default Formatting
The format() method automatically selects the most appropriate unit:
print(SizedFile.b(500).format()); // "500 B"
print(SizedFile.b(2048).format()); // "2.00 KB"
print(SizedFile.kb(1536).format()); // "1.50 MB"
print(SizedFile.mb(2048).format()); // "2.00 GB"
Custom Fraction Digits
Control the number of decimal places:
final fileSize = SizedFile.kb(1.5);
print(fileSize.format(fractionDigits: 0)); // "2 KB"
print(fileSize.format(fractionDigits: 1)); // "1.5 KB"
print(fileSize.format(fractionDigits: 3)); // "1.500 KB"
Custom Postfixes
Override the default unit labels for a single format call:
final fileSize = SizedFile.mb(5);
final customPostfixes = {
'B': 'bytes',
'KB': 'kilobytes',
'MB': 'megabytes',
'GB': 'gigabytes',
'TB': 'terabytes',
};
print(fileSize.format(postfixes: customPostfixes));
// Output: "5.00 megabytes"
Localization #
Set a global postfix generator for internationalization:
// Set custom postfixes globally (e.g., for Spanish)
SizedFile.setPostfixesGenerator(() {
return {
'B': 'B',
'KB': 'KB',
'MB': 'MB',
'GB': 'GB',
'TB': 'TB',
};
});
final fileSize = SizedFile.mb(5);
print(fileSize.format()); // Uses custom postfixes
Extension Methods #
The package provides convenient extension methods on num (both int and double) for creating SizedFile instances with a more readable syntax:
import 'package:sized_file/sized_file.dart';
// Create file sizes using extension methods
final document = 500.kb; // 500 kilobytes
final photo = 2.5.mb; // 2.5 megabytes
final video = 1.5.gb; // 1.5 gigabytes
final backup = 2.tb; // 2 terabytes
final small = 1024.b; // 1024 bytes
// Use in expressions
final total = 1.gb + 500.mb + 256.kb;
print(total.format()); // "1.49 GB"
// Works with arithmetic
final doubled = 5.mb * 2;
print(doubled.format()); // "10.00 MB"
// Chain operations
final result = 10.gb - 2.gb + 500.mb;
print(result.format()); // "8.49 GB"
Available Extensions
| Extension | Description | Example | Equivalent To |
|---|---|---|---|
.b |
Bytes | 1024.b |
SizedFile.b(1024) |
.kb |
Kilobytes | 1.5.kb |
SizedFile.kb(1.5) |
.mb |
Megabytes | 100.mb |
SizedFile.mb(100) |
.gb |
Gigabytes | 2.5.gb |
SizedFile.gb(2.5) |
.tb |
Terabytes | 1.tb |
SizedFile.tb(1) |
Note: The .b extension automatically converts to integer (truncates decimals) since bytes must be whole numbers.
Arithmetic Operations #
The SizedFile class supports arithmetic operations for calculating storage totals, quotas, and proportions.
Addition and Subtraction
// Adding file sizes
final document = SizedFile.mb(2);
final spreadsheet = SizedFile.kb(500);
final presentation = SizedFile.kb(1);
final total = document + spreadsheet + presentation;
print(total.format()); // "2.49 MB"
// Subtracting file sizes
final totalStorage = SizedFile.gb(1);
final usedSpace = SizedFile.mb(750);
final available = totalStorage - usedSpace;
print(available.format()); // "274.00 MB"
// Result is clamped to zero if negative
final small = SizedFile.kb(100);
final large = SizedFile.mb(1);
final diff = small - large;
print(diff.format()); // "0 B"
Multiplication and Division
// Multiply by scalar to scale sizes
final fileSize = SizedFile.mb(10);
final tripled = fileSize * 3;
print(tripled.format()); // "30.00 MB"
final half = fileSize * 0.5;
print(half.format()); // "5.00 MB"
// Divide by scalar
final total = SizedFile.gb(1);
final quarter = total / 4;
print(quarter.format()); // "256.00 MB"
// Calculate ratio between two sizes
final used = SizedFile.mb(250);
final capacity = SizedFile.gb(1);
final ratio = used.ratioTo(capacity);
print('${(ratio * 100).toStringAsFixed(1)}% used'); // "24.4% used"
// Calculate per-item size
final totalSize = SizedFile.gb(10);
final fileCount = 1000;
final avgSize = totalSize / fileCount;
print(avgSize.format()); // "10.49 MB"
Static Helper Methods #
Work with multiple file sizes using built-in utility methods:
final files = [
SizedFile.mb(10),
SizedFile.mb(25),
SizedFile.mb(15),
SizedFile.kb(500),
];
// Find minimum and maximum
final smallest = SizedFile.min(files);
print(smallest.format()); // "500.00 KB"
final largest = SizedFile.max(files);
print(largest.format()); // "25.00 MB"
// Calculate total size
final totalSize = SizedFile.sum(files);
print(totalSize.format()); // "50.49 MB"
// Calculate average size
final avgSize = SizedFile.average(files);
print(avgSize.format()); // "12.62 MB"
Comparable Interface #
SizedFile implements Comparable<SizedFile> for seamless sorting:
final sizes = [
SizedFile.gb(1),
SizedFile.kb(100),
SizedFile.mb(50),
SizedFile.b(500),
];
// Natural sorting with compareTo
sizes.sort(); // Uses compareTo automatically
print(sizes.first.format()); // "500 B"
print(sizes.last.format()); // "1.00 GB"
// Manual comparison
final result = sizes[0].compareTo(sizes[1]);
// Negative if smaller, 0 if equal, positive if larger
Equality and Comparison #
The SizedFile class supports equality and comparison operations, making it easy to compare file sizes regardless of the units used to create them.
Equality Operations
final size1 = SizedFile.kb(1);
final size2 = SizedFile.b(1024);
final size3 = SizedFile.mb(0.0009765625);
print(size1 == size2); // true - same size in different units
print(size2 == size3); // true - all represent 1024 bytes
print(size1 == size3); // true
// Works with collections
final uniqueSizes = <SizedFile>{size1, size2, size3};
print(uniqueSizes.length); // 1 - all are equal, so only one unique size
// Use as Map keys
final sizeMap = <SizedFile, String>{
SizedFile.mb(1): 'Small file',
SizedFile.gb(1): 'Large file',
};
Comparison Operations
final small = SizedFile.kb(500);
final medium = SizedFile.mb(1);
final large = SizedFile.gb(1);
// Less than / Greater than
print(small < medium); // true
print(large > medium); // true
// Less than or equal / Greater than or equal
print(small <= SizedFile.kb(500)); // true (equal)
print(medium >= SizedFile.mb(0.5)); // true (greater)
// Sorting file sizes
final sizes = [large, small, medium];
sizes.sort((a, b) => a.inBytes.compareTo(b.inBytes));
// Result: [small, medium, large]
// Find maximum/minimum
final maxSize = sizes.reduce((a, b) => a > b ? a : b);
final minSize = sizes.reduce((a, b) => a < b ? a : b);
print('Largest: ${maxSize.format()}'); // "1.00 GB"
print('Smallest: ${minSize.format()}'); // "500.00 KB"
Practical Use Cases
// File size validation
bool isValidFileSize(SizedFile fileSize, SizedFile maxSize) {
return fileSize <= maxSize;
}
// Storage management
void manageStorage(List<SizedFile> files, SizedFile availableSpace) {
final totalSize = files.fold<SizedFile>(
SizedFile.zero,
(sum, file) => sum + file,
);
if (totalSize > availableSpace) {
print('Not enough space! Need ${totalSize.format()}, have ${availableSpace.format()}');
}
}
// Find files larger than threshold
List<SizedFile> findLargeFiles(List<SizedFile> files, SizedFile threshold) {
return files.where((file) => file > threshold).toList();
}
Practical Examples #
Displaying File Upload Progress
void displayProgress(int uploadedBytes, int totalBytes) {
final uploaded = SizedFile.b(uploadedBytes);
final total = SizedFile.b(totalBytes);
print('Uploaded: ${uploaded.format()} of ${total.format()}');
}
displayProgress(524288, 5242880);
// Output: "Uploaded: 512.00 KB of 5.00 MB"
Comparing File Sizes
bool isFileTooLarge(int fileSizeBytes, double maxMB) {
final fileSize = SizedFile.b(fileSizeBytes);
return fileSize.inMB > maxMB;
}
if (isFileTooLarge(10485760, 5.0)) {
print('File exceeds 5 MB limit');
}
Storage Summary
void printStorageSummary(int usedBytes, int totalBytes) {
final used = SizedFile.b(usedBytes);
final total = SizedFile.b(totalBytes);
final free = SizedFile.b(totalBytes - usedBytes);
final percentUsed = (usedBytes / totalBytes * 100).toStringAsFixed(1);
print('Storage: ${used.format()} / ${total.format()} ($percentUsed% used)');
print('Available: ${free.format()}');
}
printStorageSummary(107374182400, 268435456000);
// Output:
// Storage: 100.00 GB / 250.00 GB (40.0% used)
// Available: 150.00 GB
Bandwidth Calculation
void estimateDownloadTime(int fileSizeBytes, double speedMBps) {
final fileSize = SizedFile.b(fileSizeBytes);
final seconds = fileSize.inMB / speedMBps;
print('File size: ${fileSize.format()}');
print('Speed: ${speedMBps.toStringAsFixed(2)} MB/s');
print('Estimated time: ${seconds.toStringAsFixed(1)} seconds');
}
estimateDownloadTime(52428800, 10.5);
// Output:
// File size: 50.00 MB
// Speed: 10.50 MB/s
// Estimated time: 4.8 seconds
Examples #
For more comprehensive examples, check out the example directory which includes:
- Complete working examples demonstrating all package features
- Real-world use cases like file upload progress, storage summaries, and bandwidth calculations
- Step-by-step demonstrations of formatting options and localization
- Equality and comparison operations with practical scenarios
- Collection management using SizedFile with Set, Map, and sorting
To run the examples:
cd example
dart pub get
# Run the comprehensive overview
dart run main.dart
# Run the focused equality and comparison examples
dart run equality_comparison_example.dart
See the example README for detailed information about each example.
API Reference #
Constructors #
| Constructor | Description | Example |
|---|---|---|
SizedFile.zero |
Static instance with zero bytes | SizedFile.zero |
SizedFile.b(int bytes) |
Creates instance from bytes | SizedFile.b(1024) |
SizedFile.kb(num kb) |
Creates instance from kilobytes | SizedFile.kb(1.5) |
SizedFile.mb(num mb) |
Creates instance from megabytes | SizedFile.mb(100) |
SizedFile.gb(num gb) |
Creates instance from gigabytes | SizedFile.gb(2.5) |
SizedFile.tb(num tb) |
Creates instance from terabytes | SizedFile.tb(1) |
SizedFile.units({...}) |
Creates from multiple units | SizedFile.units(gb: 2, mb: 500) |
Properties #
| Property | Type | Description |
|---|---|---|
inBytes |
int |
Size in bytes |
inKB |
double |
Size in kilobytes |
inMB |
double |
Size in megabytes |
inGB |
double |
Size in gigabytes |
inTB |
double |
Size in terabytes |
Methods #
format({int fractionDigits = 2, Map<String, String>? postfixes})
Formats the file size with the most appropriate unit.
Parameters:
fractionDigits(optional): Number of decimal places (default: 2)postfixes(optional): Custom unit labels
Returns: Formatted string representation
setPostfixesGenerator(Map<String, String> Function() generator)
Static method to set a global postfix generator for all instances.
Parameters:
generator: Function that returns a map of unit postfixes
Operators #
Equality Operators
| Operator | Description | Example |
|---|---|---|
== |
Equality comparison | SizedFile.kb(1) == SizedFile.b(1024) |
hashCode |
Hash code for collections | Used automatically in Set and Map |
Comparison Operators
| Operator | Description | Example |
|---|---|---|
< |
Less than | SizedFile.kb(1) < SizedFile.mb(1) |
<= |
Less than or equal | SizedFile.kb(1) <= SizedFile.b(1024) |
> |
Greater than | SizedFile.mb(1) > SizedFile.kb(1) |
>= |
Greater than or equal | SizedFile.mb(1) >= SizedFile.b(1048576) |
Arithmetic Operators
| Operator | Description | Returns | Example |
|---|---|---|---|
+ |
Addition | SizedFile |
SizedFile.mb(1) + SizedFile.kb(500) |
- |
Subtraction (clamped to 0) | SizedFile |
SizedFile.mb(2) - SizedFile.kb(500) |
* |
Multiplication by scalar | SizedFile |
SizedFile.mb(10) * 3 |
/ |
Division by scalar | SizedFile |
SizedFile.mb(30) / 3 |
Other Methods
| Method | Description | Example |
|---|---|---|
toString() |
String representation | SizedFile.mb(1.5).toString() returns "1.50 MB" |
compareTo() |
Comparable implementation | size1.compareTo(size2) returns int |
ratioTo() |
Calculate ratio to another size | used.ratioTo(total) returns double |
Static Methods #
| Method | Description | Example |
|---|---|---|
min(sizes) |
Returns smallest size from collection | SizedFile.min([size1, size2, size3]) |
max(sizes) |
Returns largest size from collection | SizedFile.max([size1, size2, size3]) |
sum(sizes) |
Sum of all sizes | SizedFile.sum([size1, size2, size3]) |
average(sizes) |
Average of all sizes | SizedFile.average([size1, size2, size3]) |
setPostfixesGenerator() |
Set global postfix generator | SizedFile.setPostfixesGenerator(fn) |
Understanding the Divider #
This package uses 1024 as the divider (binary) rather than 1000 (decimal):
- 1 KB = 1,024 bytes
- 1 MB = 1,024 KB = 1,048,576 bytes
- 1 GB = 1,024 MB = 1,073,741,824 bytes
- 1 TB = 1,024 GB = 1,099,511,627,776 bytes
This aligns with how operating systems and storage devices typically report file sizes.
Testing #
The package includes comprehensive unit tests covering:
- All constructors and conversions
- Formatting with various options
- Edge cases and boundary conditions
- Custom postfix generators
- Localization scenarios
- Equality and comparison operations
- Hash code consistency
- Collection behavior (Set, Map)
- Sorting and ordering
- Arithmetic operations (+, -, *, /)
- Static helper methods (min, max, sum, average)
- Comparable interface implementation
Run tests with:
dart test
Or with Flutter:
flutter test
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog #
See CHANGELOG.md for a list of changes in each version.
Support #
If you encounter any issues or have questions:
- Check the API Reference section
- Look at the examples
- Open an issue on GitHub
Made with ❤️ for the Dart and Flutter community