We all know how to use path_provider to obtain the file path of Flutter, but the meaning of the directory is not clear. This article introduces the Android and iOS file directories, and the recommended directories for different scenarios.

Different platforms have different file systems, such as file paths. Therefore, obtaining file paths from a Flutter requires native support. The native side passes file paths to a Flutter through MethodChannel. It is recommended that you use the plugin path_Provider maintained by Google.

Pub: pub.flutter-io.cn/packages/pa…

Github address: github.com/flutter/plu…

Add the dependent

Add dependencies to the project’s pubspec.yaml file:

dependencies:
  path_provider: ^1.614.
Copy the code

Execute command:

flutter pub get
Copy the code

The file path

Path_provider (Version: 1.6.14) Provides 8 ways to obtain different file paths. Currently, Flutter is only released on Android and iOS. Therefore, the following describes only the file paths for the Android and iOS platforms.

  • getTemporaryDirectory

    This directory can be cleared at any time. This directory is a private directory for applications and cannot be accessed by other applications.

    On Android, it corresponds to getCacheDir.

    NSCachesDirectory on iOS.

  • getApplicationSupportDirectory

    The path to the directory where an application can put application support files.

    Use this file for files that you do not want to expose to users. Your application should not use this directory to hold user data files.

    On iOS, corresponding NSApplicationSupportDirectory, if this directory does not exist, will be automatically created. On Android, this corresponds to getFilesDir.

  • getLibraryDirectory

    Applications can store persistent files, backup files, and directory paths for files that are not visible to the user, such as storage.sqlite.db.

    On Android, this function raises an [UnsupportedError] exception, and no equivalent item path exists.

  • getApplicationDocumentsDirectory

    The application may place directory paths in it for user-generated data or data that the application cannot recreate.

    On iOS, this corresponds to the NSDocumentDirectory API. If the data is not user generated, consider using [getApplicationSupportDirectory].

    On Android, this corresponds to the getDataDirectory API. If you want to let users see the data, please consider to switch to [external.getexternalstoragedirectory].

  • getExternalStorageDirectory

    The path to the directory where the top-level storage can be accessed by the application. Since this feature is only available on Android, you should determine the current operating system before issuing this function call.

    On iOS, this feature raises an [UnsupportedError] exception because it cannot be accessed outside the application sandbox.

    On Android, this corresponds to getExternalFilesDir (null).

  • getExternalCacheDirectories

    The path to the directory that stores application-specific external cached data. These paths are typically located on external storage, such as a separate partition or SD card. A phone may have multiple storage directories available. Since this feature is only available on Android, you should determine the current operating system before issuing this function call. On iOS, this feature raises UnsupportedError because it is impossible to access outside the application sandbox.

    On Android, corresponding to the Context. GetExternalCacheDirs () or API Level is lower than the 19 Context. GetExternalCacheDir ().

  • getExternalStorageDirectories

    The path to a directory where application-specific data can be stored. These paths are typically located on external storage, such as a separate partition or SD card. Since this feature is only available on Android, you should determine the current operating system before issuing this function call. On iOS, this feature raises UnsupportedError because it is impossible to access outside the application sandbox. On Android, corresponding to the Context. GetExternalFilesDirs (String type) or API Level is lower than the 19 Context. GetExternalFilesDir (String type).

  • getDownloadsDirectory

    The path to the directory where downloaded files are stored, which is usually only relevant to the desktop operating system. On Android and iOS, this function raises an [UnsupportedError] exception.

If you don’t have Android or iOS development experience, you should be confused by the instructions above. Which path do you use? What’s the difference? The following describes the file paths from the perspective of Android and iOS platforms, and provides suggestions on how to use the paths and precautions when using them.

Android File Storage

Android file storage is divided into internal storage and external storage.

Internal storage

The created files are in the package name directory of the application. Phones without root permission cannot see this directory in the file management application of the mobile phone. However, you can use the Android Studio tool to view the directory: data/data/ package name:

Look at the directory structure of the package name:

  • Cache directory: Corresponds to the getTemporaryDirectory method, which is used to cache files and may be purged by the system at any time.
  • Files directory: corresponding getApplicationSupportDirectory method.
  • Code_cache: This directory stores Flutter code and resources.
    • Flutter_engine/SKia: Flutter rendering engine.
    • Flutter_guidePVWGWK/Flutter_guide /build/ Flutter_assets: Flutter resource files.
  • Shared_prefs: default path for SharePreferences.
  • Corresponding getApplicationDocumentsDirectory app_flutter: method.
  • App_flutter /dbName: Uses the default path of SQLite. Sqlite can also specify the location.

SharePreferences and SQLite are two third-party plug-ins that save data.

Internal storage features:

  • Security. Other applications cannot access the data.
  • When the application is uninstalled, the data is also deleted to avoid garbage files.
  • No additional permissions are required.
  • The storage space is limited. The data in this directory may be cleared by the system at any time. You can also clear the data in this directory by setting clear data.
  • Domestic characteristics, different mobile phone manufacturers have different restrictions on the directory, such as the total size limit, the space limit of a single application, different data clearance policies, etc.

External storage

External storage can be viewed through the phone’s file management app,

There is a special directory inside: Android/data/ package name:

A package name represents an application:

  • : if the cache directory, cache getExternalCacheDirectories method.
  • Files: corresponding getExternalStorageDirectories method.

Features of this directory:

  • When the application is uninstalled, the data is also deleted to avoid garbage files.
  • No additional permissions are required.
  • The space is large and will not be cleared by the system. You can clear the data in this directory by setting clear data.
  • Users can directly delete or import files.

External storage in addition to the Android/data/ directory, there are directories of the same level as this directory, features:

  • All applications are accessible.
  • Users can directly delete or import files.
  • You need to apply for read and write permission.

Android’s official directory management is more and more strict, the Android system for 11 has been enforced partition storage, see: developer.android.com/preview/pri…

With all that said, here’s the summary:

  • The SharePreferences and SQLite data are recommended to be stored internally, and the plug-in has done that for us without manual processing.
  • Strictly confidential data, such as user data, it is suggested that stored in internal storage and corresponding getApplicationSupportDirectory method.
  • All the other data that suggests to deposit the Android/data/package name, corresponding getExternalCacheDirectories and getExternalStorageDirectories method.

IOS File Storage

IOS file storage is much simpler than Android, because iOS is very strict about user privacy protection. Each iOS application has a separate file system and can only be operated in the corresponding file system. This area is called sandbox.

Each app sandbox contains three folders: Documents, Library, and TMP:

  • Documents: Application data files are written to this directory. This directory is used to store user data. Save application important data files and user data files, etc. Sync to iTunes backup when the directory, corresponding getApplicationDocumentsDirectory method.
  • Library: the correspondinggetLibraryDirectoryMethods.
    • Caches: Holds support files, cache files, log files, etc. generated during application use, such as downloaded music, videos,SDWebImage Caches, etc. Corresponds to the getTemporaryDirectory method.
    • Preferences: Contains the application’s Preferences file, which iCloud backs up.
    • Application Support: corresponding getApplicationSupportDirectory method.
  • TMP: Stores temporary files that cannot be backed up and can be deleted at any time. The cache data is cleared every three days.

Path_provider use

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

///
/// desc:
///

class PathProviderDemo extends StatefulWidget {
  @override
  _PathProviderDemoState createState() => _PathProviderDemoState();
}

class _PathProviderDemoState extends State<PathProviderDemo> {
  Future<Directory> _tempDirectory;
  Future<Directory> _appSupportDirectory;
  Future<Directory> _appLibraryDirectory;
  Future<Directory> _appDocumentsDirectory;
  Future<Directory> _externalStorageDirectory;
  Future<List<Directory>> _externalStorageDirectories;
  Future<List<Directory>> _externalCacheDirectories;
  Future<Directory> _downloadDirectory;

  @override
  void initState() {
    super.initState();
    setState(() {
      _tempDirectory = getTemporaryDirectory();
      _appSupportDirectory = getApplicationSupportDirectory();
      _appLibraryDirectory = getLibraryDirectory();
      _appDocumentsDirectory = getApplicationDocumentsDirectory();
      _externalStorageDirectory = getExternalStorageDirectory();
      _externalCacheDirectories = getExternalCacheDirectories();
      _externalStorageDirectories = getExternalStorageDirectories();
      _downloadDirectory = getDownloadsDirectory();
    });
  }

  Widget _buildDirectory(
      BuildContext context, AsyncSnapshot<Directory> snapshot) {
    Text text = const Text(' ');
    if (snapshot.connectionState == ConnectionState.done) {
      if (snapshot.hasError) {
        text = Text('Error: ${snapshot.error}');
      } else if (snapshot.hasData) {
        text = Text('path: ${snapshot.data.path}');
      } else {
        text = const Text('path unavailable'); }}return Padding(padding: EdgeInsets.symmetric(horizontal: 16), child: text);
  }

  Widget _buildDirectories(
      BuildContext context, AsyncSnapshot<List<Directory>> snapshot) {
    Text text = const Text(' ');
    if (snapshot.connectionState == ConnectionState.done) {
      if (snapshot.hasError) {
        text = Text('Error: ${snapshot.error}');
      } else if (snapshot.hasData) {
        final String combined =
            snapshot.data.map((Directory d) => d.path).join(', ');
        text = Text('paths: $combined');
      } else {
        text = const Text('path unavailable'); }}return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16), child: text);
  }

  Widget _buildItem(String title, Future<Directory> future) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          child: Text(title),
        ),
        FutureBuilder<Directory>(future: future, builder: _buildDirectory),
      ],
    );
  }

  Widget _buildItem1(String title, Future<List<Directory>> future) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          child: Text(title),
        ),
        FutureBuilder<List<Directory>>(
            future: future,
            builder: _buildDirectories),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: ListView(
          itemExtent: 120,
          children: <Widget>[
            _buildItem('getTemporaryDirectory', _tempDirectory),
            _buildItem('getApplicationSupportDirectory', _appSupportDirectory),
            _buildItem('getLibraryDirectory', _appLibraryDirectory),
            _buildItem(
                'getApplicationDocumentsDirectory', _appDocumentsDirectory),
            _buildItem(
                'getExternalStorageDirectory', _externalStorageDirectory),
            _buildItem('getDownloadsDirectory', _downloadDirectory),

            _buildItem1('getExternalStorageDirectories',_externalStorageDirectories),
            _buildItem1('getExternalCacheDirectories',_externalCacheDirectories), ], ), ), ); }}Copy the code

Each path of Android system:

IOS system paths:

communication

Lao Meng Flutter blog (330 controls usage + practical primer series) : laomengit.com