This tutorial shows you how to get the size of a file or a directory in Flutter.
If your Flutter application needs to know the size of a file or a directory in the local storage, it can be done in a simple way. Dart already provides the functionality to get the file size. However, you may also need to handle storage permission. Below are the examples of how to get the size of a file or a directory in Flutter.
Dependencies
If you create an Android or iOS application using Flutter, getting the size of a file or a directory requires access permission if it's not located in the application's directory. If that's the case, the application needs to ask storage permission. Using a plugin such as permission_handler
makes it easier to ask for storage permission. Modify the pubspec.yaml
of your project to add the dependency.
dependencies:
permission_handler: ^10.2.0
Get File Size
First, you need to create a File
object by passing the path to the file. The File
class has a method named readAsBytes
which returns a Future
of Uint8List
. Then, you can get the file size in bytes by accessing lengthInBytes
property.
Future<int> _getFileSize(String path) async {
final fileBytes = await File(path).readAsBytes();
return fileBytes.lengthInBytes;
}
The above function returns the result in bytes. If you want to get the size in other units such as KB, MB, GB, or TB, just add the computation like the code below.
final fileSizeInBytes = await _getFileSize(path);
final fileSizeInKB = fileSizeInBytes / 1000;
final fileSizeInMB = fileSizeInKB / 1000;
final fileSizeInGB = fileSizeInMB / 1000;
final fileSizeInTB = fileSizeInGB / 1000;
Get Directory Size
To get the size of a directory, first you need to create an instance of Directory
by calling the constructor and passing the path of the directory. The Directory
class has a method named list
. It can be used to list all subdirectories and files of the current directory. To choose whether to include only the files right under the current directory (non-recursive) or also take into account all files in the subdirectories (recursive), there is an optional named argument recursive
which defaults to false.
Stream<FileSystemEntity> list(
{bool recursive = false, bool followLinks = true}
)
The method returns a Stream
and you can convert the result to a List
by using Stream
's toList
method. After getting the list of files, you can sum the size of each file to get the total size of the directory.
Future<int> _getDirectorySize(String path, bool isRecursive) async {
var totalSize = 1;
final entityList = await Directory(path).list(recursive: isRecursive).toList();
await Future.forEach(entityList, (entity) async {
if (entity is File) {
final fileBytes = await File(entity.path).readAsBytes();
totalSize += fileBytes.lengthInBytes;
}
});
return totalSize;
}
Get Permission
This part is only necessary if you want to access files or directories not in the application's directory. Otherwise you can skip it (and no need to add the permission_handler
dependency).
For Android, edit the android/app/src/main/AndroidManifest.xml
file by adding READ_EXTERNAL_STORAGE
permission.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.woolha.flutterexample">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application>
...
</application>
</manifest>
Before the code for getting the size of a file or a directory, you need to add the code below. It's used to ask for storage permission to the user if the application hasn't been granted the permission. For adding the code below, it's required to import package:permission_handler/permission_handler.dart
.
await Permission.storage.request().isGranted;
Full Code
Below is a Flutter application that checks the size of a file or a folder. It already handles the storage permission to make it possible to access files not located in the application's directory.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Woolha.com Flutter Tutorial',
home: GetSizeExample(),
);
}
}
class GetSizeExample extends StatefulWidget {
const GetSizeExample({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _GetSizeExampleState();
}
}
class _GetSizeExampleState extends State<GetSizeExample> {
final TextEditingController _textEditingController = TextEditingController();
String? _result;
bool _isRecursive = false;
Future<int> _getFileSize(String path) async {
final fileBytes = await File(path).readAsBytes();
return fileBytes.lengthInBytes;
}
Future<int> _getDirectorySize(String path, bool isRecursive) async {
var totalSize = 1;
final entityList = await Directory(path).list(recursive: isRecursive).toList();
await Future.forEach(entityList, (entity) async {
if (entity is File) {
final fileBytes = await File(entity.path).readAsBytes();
totalSize += fileBytes.lengthInBytes;
}
});
print('totalSize: $totalSize');
return totalSize;
}
Future<void> _displayFileSize(String path) async {
final fileSizeInBytes = await _getFileSize(path);
_displaySize(fileSizeInBytes);
}
Future<void> _displayDirectorySize(String path, bool isRecursive) async {
final fileSizeInBytes = await _getDirectorySize(path, isRecursive);
_displaySize(fileSizeInBytes);
}
void _displaySize(int fileSizeInBytes) {
final fileSizeInKB = fileSizeInBytes / 1000;
final fileSizeInMB = fileSizeInKB / 1000;
final fileSizeInGB = fileSizeInMB / 1000;
final fileSizeInTB = fileSizeInGB / 1000;
final fileSize = '''
$fileSizeInBytes bytes
$fileSizeInKB KB
$fileSizeInMB MB
$fileSizeInGB GB
$fileSizeInTB TB
''';
setState(() {
_result = fileSize;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Woolha.com Flutter Tutorial'),
backgroundColor: Colors.teal,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: _textEditingController,
decoration: const InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
hintText: 'Enter path',
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Recursive'),
Switch(
value: _isRecursive,
onChanged: (val) {
setState(() {
_isRecursive = val;
});
},
),
],
),
OutlinedButton(
onPressed: () async {
await Permission.storage.request().isGranted;
await _displayFileSize(_textEditingController.text);
},
child: const Text('Get file size', style: TextStyle(color: Colors.teal)),
),
OutlinedButton(
onPressed: () async {
await Permission.storage.request().isGranted;
await _displayDirectorySize(_textEditingController.text, _isRecursive);
},
child: const Text('Get directory size', style: TextStyle(color: Colors.teal)),
),
Text('Result: ${_result ?? '-'}', style: const TextStyle(color: Colors.teal)),
],
),
),
);
}
}
Summary
Getting the file size in Flutter is quite simple. You can create a File
object, get the bytes using readAsBytes()
, and access the lengthInBytes
property. For directory, you can get the list of files by using Directory
's list
method, then sum the size of each file. If the file or directory to be checked is outside the application's directory, your application has to request storage permission.
You can also read about: