Flutter - Get File or Directory Size Examples

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: