Répertoire du système de fichiers [Flutter réel combat]

Guide de Lao Meng : Nous savons tous que path_provider est utilisé pour obtenir les chemins de fichiers dans Flutter , mais la signification de son répertoire n'est pas très claire. Cet article présente les répertoires de fichiers des systèmes Android et iOS et les répertoires recommandés dans différents scénarios.

Les systèmes de fichiers correspondant aux différentes plates-formes sont différents, tels que les chemins de fichiers. Par conséquent, l'obtention des chemins de fichiers dans Flutter nécessite une prise en charge native. Le côté natif transmet le chemin du fichier à Flutter via MethodChannel. S'il n'y a pas d'exigence particulière, il est recommandé d'utiliser le plugin Google officiel path_provider .

Adresse de pub: https://pub.flutter-io.cn/packages/path_provider

Adresse Github: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider

Ajouter une dépendance

Dans le pubspec.yamlfichier projet pour ajouter des dépendances:

dependencies:
  path_provider: ^1.6.14

Exécution d'une commande:

flutter pub get

chemin du fichier

path_provider (version: 1.6.14) fournit 8 méthodes pour obtenir différents chemins de fichiers. Actuellement, Flutter (Flutter 1.20.1 • channel stable) ne publie que la version officielle d'Android et iOS, donc seuls les fichiers pour les plates-formes Android et iOS sont présentés ci-dessous chemin.

  • getTemporaryDirectory

    Répertoire temporaire, adapté aux fichiers cache téléchargés, ce répertoire peut être effacé à tout moment, ce répertoire est un répertoire privé de l'application, les autres applications ne peuvent pas accéder à ce répertoire.

    Correspondant sur Android getCacheDir.

    Correspond à iOS NSCachesDirectory.

  • getApplicationSupportDirectory

    Chemin d'accès au répertoire dans lequel l'application peut placer les fichiers de prise en charge de l'application.

    Utilisez ce fichier pour les fichiers que vous ne souhaitez pas divulguer aux utilisateurs. Votre application ne doit pas utiliser ce répertoire pour stocker les fichiers de données utilisateur.

    Sur iOS NSApplicationSupportDirectory, si ce répertoire n'existe pas, il sera créé automatiquement. Sur Android, nous correspondons getFilesDir.

  • getLibraryDirectory

    L'application peut stocker des fichiers persistants, des fichiers de sauvegarde et des chemins de répertoire pour les fichiers qui ne sont pas visibles par les utilisateurs, tels que storage.sqlite.db.

    Sur Android, cette fonction lève une exception [UnsupportedError] et aucun chemin équivalent n'existe.

  • getApplicationDocumentsDirectory

    Chemin du répertoire dans lequel l'application peut placer des données générées par l'utilisateur ou des données que l'application ne peut pas recréer.

    Sur iOS, cela correspond à l' NSDocumentDirectoryAPI. Si les données ne sont pas générées par l'utilisateur, envisagez d'utiliser [getApplicationSupportDirectory].

    Sur Android, cela correspond à l' getDataDirectoryAPI. Si vous souhaitez que les utilisateurs voient les données, envisagez d'utiliser [getExternalStorageDirectory] à la place.

  • getExternalStorageDirectory

    Chemin du répertoire dans lequel l'application peut accéder au stockage de niveau supérieur. Étant donné que cette fonctionnalité n'est disponible que sur Android, le système d'exploitation actuel doit être déterminé avant d'émettre cet appel de fonction.

    Sur iOS, cette fonctionnalité lèvera une exception [UnsupportedError] car elle n'est pas accessible en dehors du bac à sable de l'application.

    Sur Android, nous correspondons getExternalFilesDir(null).

  • getExternalCacheDirectories

    Chemin d'accès au répertoire dans lequel les données de cache externe spécifiques à l'application sont stockées. Ces chemins sont généralement situés sur un stockage externe (comme une partition séparée ou une carte SD). Le téléphone peut avoir plusieurs répertoires de stockage disponibles. Étant donné que cette fonctionnalité n'est disponible que sur Android, le système d'exploitation actuel doit être déterminé avant d'émettre cet appel de fonction. Sur iOS, cette fonctionnalité lèvera un UnsupportedError car il est impossible d'accéder en dehors du bac à sable de l'application.

    Sur Android, le niveau correspondant Context.getExternalCacheDirs()ou API est inférieur à 19 Context.getExternalCacheDir().

  • getExternalStorageDirectories

    Chemin d'accès au répertoire dans lequel les données spécifiques à l'application peuvent être stockées. Ces chemins sont généralement situés sur un stockage externe (comme une partition séparée ou une carte SD). Étant donné que cette fonctionnalité n'est disponible que sur Android, le système d'exploitation actuel doit être déterminé avant d'émettre cet appel de fonction. Sur iOS, cette fonctionnalité lèvera un UnsupportedError car il est impossible d'accéder en dehors du bac à sable de l'application. Sur Android, le niveau correspondant Context.getExternalFilesDirs(String type)ou API est inférieur à 19 Context.getExternalFilesDir(String type).

  • getDownloadsDirectory

    Chemin d'accès au répertoire dans lequel le fichier téléchargé est stocké. Il est généralement uniquement lié au système d'exploitation du bureau. Sur Android et iOS, cette fonction lèvera une exception [UnsupportedError].

S'il n'y a pas d'expérience de développement Android ou iOS, la lecture de la description ci-dessus devrait sembler ignorante , et avec autant de chemins à la fin quoi? Quelle est la différence? Ce qui suit présente son chemin de fichier du point de vue des plates-formes Android et iOS, et donne enfin des suggestions sur l'utilisation du chemin et les questions auxquelles il faut prêter attention lors de l'utilisation.

Stockage de fichiers Android

Le stockage de fichiers Android est divisé en stockage interne et stockage externe .

Stockage interne

Les fichiers privés utilisés pour stocker des applications, d'autres applications ne peuvent pas accéder aux données, les fichiers créés dans le répertoire pour ce nom de package d'application, sans privilèges root, le téléphone portable ne peut pas être dans le gestionnaire de fichiers pour voir cette application de répertoire, mais vous pouvez par Android Studio Vue de l'outil, le chemin est: données / données / nom du package:

Regardez la structure de répertoires spécifique sous le nom du package:

  • répertoire cache: correspondant à la méthode getTemporaryDirectory , utilisée pour mettre en cache les fichiers, ce répertoire peut être effacé par le système à tout moment.
  • répertoire files: correspondant à la méthode getApplicationSupportDirectory .
  • code_cache: ce répertoire stocke le code et les ressources liés à Flutter.
    • flutter_engine / skia: moteur de rendu Flutter.
    • flutter_guidePVWGWK / flutter_guide / build / flutter_assets : Flutter 资源 文件。
  • shared_prefs: le chemin par défaut de SharePreferences .
  • app_flutter: correspond à la méthode getApplicationDocumentsDirectory .
  • app_flutter / dbName: Utiliser du chemin par défaut, SQLite peut également spécifier l'emplacement.

SharePreferences et sqlite sont deux plug-ins tiers qui enregistrent des données.

Caractéristiques du stockage interne:

  • Sécurité, les autres applications ne peuvent pas accéder à ces données.
  • Lorsque l'application est désinstallée, ces données seront également supprimées pour éviter les fichiers indésirables.
  • Pas besoin de demander des autorisations supplémentaires.
  • Espace de stockage limité, ce répertoire peut être effacé à tout moment du système de données, vous pouvez également définir les données d'effacement pour effacer ces données de répertoire.
  • Compte tenu des caractéristiques nationales , différents fabricants de téléphones mobiles ont imposé différentes restrictions à ce catalogue, telles que des restrictions de taille globale, des restrictions sur la taille de l'espace occupé par une seule application et différentes stratégies de compensation des données.

Stockage externe

Le stockage externe peut le gestionnaire de fichiers du téléphone pour afficher l'application,

Il existe un répertoire spécial: Android / data / nom du package:

Voyant que ce répertoire ressemble beaucoup au répertoire de stockage interne, un nom de package représente une application:

  • cache: répertoire de cache, correspondant à la méthode getExternalCacheDirectories .
  • files: correspondant à la méthode getExternalStorageDirectories .

Caractéristiques de ce catalogue:

  • Lorsque l'application est désinstallée, ces données seront également supprimées pour éviter les fichiers indésirables.
  • Pas besoin de demander des autorisations supplémentaires.
  • L' espace est grand et le système ne sera pas effacé, par la mise des données claires pour effacer ces données de répertoire.
  • Les utilisateurs peuvent directement supprimer et importer des fichiers.

En plus du répertoire Android / data / , le stockage externe a également un répertoire au même niveau que ce répertoire. Caractéristiques:

  • Toutes les applications sont accessibles.
  • Les utilisateurs peuvent directement supprimer et importer des fichiers.
  • Besoin de demander des autorisations de lecture et d'écriture .

La gestion officielle Android de cet annuaire devient de plus en plus stricte. Le système Android 11 a commencé à appliquer le stockage de partition. Pour plus de détails, veuillez consulter: https://developer.android.com/preview/privacy/storage?hl=zh-cn

Tant de choses ont été dites ci-dessus, résumées comme suit:

  • Il est recommandé de stocker les données SharePreferences et sqlite dans la mémoire interne. Le plug-in l'a déjà fait pour nous, sans traitement manuel.
  • Il est recommandé de stocker des données strictement confidentielles, telles que les données utilisateur, dans le stockage interne, correspondant à la méthode getApplicationSupportDirectory .
  • Il est recommandé de stocker toutes les autres données dans Android / data / package name / , correspondant aux méthodes getExternalCacheDirectories et getExternalStorageDirectories .

Stockage de fichiers iOS

Le stockage de fichiers iOS est beaucoup plus simple qu'Android, car iOS est très strict en matière de protection de la confidentialité des utilisateurs. Chaque application iOS possède un système de fichiers distinct et ne peut être utilisée que dans le système de fichiers correspondant. Cette zone est appelée Bac à sable.

Chaque sandbox d'application contient 3 dossiers: Documents, Library et tmp:

  • Documents: les fichiers de données d'application sont écrits dans ce répertoire. Ce répertoire est utilisé pour stocker les données utilisateur. Enregistrez les fichiers de données importants et les fichiers de données utilisateur de l'application. iTunes sauvegardera ce répertoire pendant la synchronisation, ce qui correspond à la méthode getApplicationDocumentsDirectory .
  • Bibliothèque: correspond à la méthode getLibraryDirectory .
    • Caches: enregistrez les fichiers de support, les fichiers de cache, les fichiers journaux, etc. générés lorsque l'application est utilisée, tels que la musique téléchargée, la vidéo, le cache SDWebImage, etc. Correspond à la méthode getTemporaryDirectory .
    • Préférences: contient le fichier de configuration des préférences de l'application, iCloud sauvegardera les informations de configuration.
    • Prise en charge des applications: correspond à la méthode getApplicationSupportDirectory .
  • tmp: Stocke les fichiers temporaires et ne seront pas sauvegardés, et les données de ce fichier peuvent être effacées à tout moment. Selon la déclaration officielle, les données mises en cache sont nettoyées tous les trois jours.

utilisation de path_provider

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),

          ],
        ),
      ),
    );
  }
}

Chaque chemin du système Android:

Différents chemins du système iOS:

communiquer avec

communiquer avec

Blog Laomeng Flutter (330 contrôles d'utilisation + série d'introduction au combat): http://laomengit.com

Bienvenue à rejoindre le groupe d'échange Flutter (WeChat: laomengit) et à suivre le compte public [Lao Meng Flutter]:

Je suppose que tu aimes

Origine blog.csdn.net/mengks1987/article/details/108657135
conseillé
Classement