Flutter實(shí)戰(zhàn) 文件操作

2021-03-09 10:11 更新

Dart 的 IO 庫包含了文件讀寫的相關(guān)類,它屬于 Dart 語法標(biāo)準(zhǔn)的一部分,所以通過 Dart IO 庫,無論是 Dart VM 下的腳本還是 Flutter,都是通過 Dart IO 庫來操作文件的,不過和 Dart VM 相比, Flutter 有一個(gè)重要差異是文件系統(tǒng)路徑不同,這是因?yàn)?Dart VM 是運(yùn)行在 PC 或服務(wù)器操作系統(tǒng)下,而 Flutter 是運(yùn)行在移動(dòng)操作系統(tǒng)中,他們的文件系統(tǒng)會(huì)有一些差異。

#APP目錄

Android 和 iOS 的應(yīng)用存儲(chǔ)目錄不同,PathProvider (opens new window)插件提供了一種平臺(tái)透明的方式來訪問設(shè)備文件系統(tǒng)上的常用位置。該類當(dāng)前支持訪問兩個(gè)文件系統(tǒng)位置:

  • 臨時(shí)目錄: 可以使用 getTemporaryDirectory() 來獲取臨時(shí)目錄; 系統(tǒng)可隨時(shí)清除的臨時(shí)目錄(緩存)。在 iOS 上,這對應(yīng)于NSTemporaryDirectory() (opens new window)返回的值。在 Android 上,這是getCacheDir() (opens new window)返回的值。
  • 文檔目錄: 可以使用getApplicationDocumentsDirectory()來獲取應(yīng)用程序的文檔目錄,該目錄用于存儲(chǔ)只有自己可以訪問的文件。只有當(dāng)應(yīng)用程序被卸載時(shí),系統(tǒng)才會(huì)清除該目錄。在iOS上,這對應(yīng)于NSDocumentDirectory。在 Android 上,這是AppData目錄。
  • 外部存儲(chǔ)目錄:可以使用getExternalStorageDirectory()來獲取外部存儲(chǔ)目錄,如 SD 卡;由于 iOS 不支持外部目錄,所以在 iOS 下調(diào)用該方法會(huì)拋出UnsupportedError異常,而在 Android 下結(jié)果是 android SDK 中getExternalStorageDirectory的返回值。

一旦你的 Flutter 應(yīng)用程序有一個(gè)文件位置的引用,你可以使用 dart:io (opens new window)API 來執(zhí)行對文件系統(tǒng)的讀/寫操作。有關(guān)使用 Dart 處理文件和目錄的詳細(xì)內(nèi)容可以參考 Dart 語言文檔,下面我們看一個(gè)簡單的例子。

#示例

我們還是以計(jì)數(shù)器為例,實(shí)現(xiàn)在應(yīng)用退出重啟后可以恢復(fù)點(diǎn)擊次數(shù)。 這里,我們使用文件來保存數(shù)據(jù):

  1. 引入 PathProvider 插件;在pubspec.yaml文件中添加如下聲明:

   path_provider: ^0.4.1

添加后,執(zhí)行flutter packages get 獲取一下, 版本號(hào)可能隨著時(shí)間推移會(huì)發(fā)生變化,讀者可以使用最新版。

  1. 實(shí)現(xiàn):

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

   
   class FileOperationRoute extends StatefulWidget {
     FileOperationRoute({Key key}) : super(key: key);

   
     @override
     _FileOperationRouteState createState() => new _FileOperationRouteState();
   }

   
   class _FileOperationRouteState extends State<FileOperationRoute> {
     int _counter;

   
     @override
     void initState() {
       super.initState();
       //從文件讀取點(diǎn)擊次數(shù)
       _readCounter().then((int value) {
         setState(() {
           _counter = value;
         });
       });
     }

   
     Future<File> _getLocalFile() async {
       // 獲取應(yīng)用目錄
       String dir = (await getApplicationDocumentsDirectory()).path;
       return new File('$dir/counter.txt');
     }

   
     Future<int> _readCounter() async {
       try {
         File file = await _getLocalFile();
         // 讀取點(diǎn)擊次數(shù)(以字符串)
         String contents = await file.readAsString();
         return int.parse(contents);
       } on FileSystemException {
         return 0;
       }
     }

   
     Future<Null> _incrementCounter() async {
       setState(() {
         _counter++;
       });
       // 將點(diǎn)擊次數(shù)以字符串類型寫到文件中
       await (await _getLocalFile()).writeAsString('$_counter');
     }

   
     @override
     Widget build(BuildContext context) {
       return new Scaffold(
         appBar: new AppBar(title: new Text('文件操作')),
         body: new Center(
           child: new Text('點(diǎn)擊了 $_counter 次'),
         ),
         floatingActionButton: new FloatingActionButton(
           onPressed: _incrementCounter,
           tooltip: 'Increment',
           child: new Icon(Icons.add),
         ),
       );
     }
   }

上面代碼比較簡單,不再贅述,需要說明的是,本示例只是為了演示文件讀寫,而在實(shí)際開發(fā)中,如果要存儲(chǔ)一些簡單的數(shù)據(jù),使用 shared_preferences 插件會(huì)比較簡單。

注意,Dart IO 庫操作文件的 API 非常豐富,但本書不是介紹 Dart 語言的,故不詳細(xì)說明,讀者需要的話可以自行學(xué)習(xí)。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)