dart系列之:如絲滑般柔順,操作文件和目錄


簡介

文件操作是IO中非常常見的一種操作,那么對應dart語言來說,操作文件是不是很簡單呢?實際上dart提供了兩種讀取文件的方式,一種是一次性全部讀取,一種是將文件讀取為流。

一次性讀取的缺點是需要將文件內容一次性全部載入到內存中,如果遇到文件比較大的情況,就會比較尷尬。所以還需要流式讀取文件的方式。一起來看看dart中這兩種文件的讀取方式吧。

File

事實上dart中有很多地方都有File這個類,這里我們要講解的File類是dart:io包中的。

讀取整個文件

File代表一個整體的文件,他有三個構造函數,分別是:

factory File(String path) 

factory File.fromUri(Uri uri)

factory File.fromRawPath(Uint8List rawPath)

其中最常用的就是第一個構造函數。

我們可以這樣來構造一個文件:

var file = File('file.txt');

有了文件之后,就可以調用File中的各種讀取方法。

文件讀取本身有兩種形式,一種是文本,一種是二進制。

如果是文本文件,File提供了readAsString的方法,將整個文件讀取為字符串。

  Future<String> readAsString({Encoding encoding: utf8});

我們可以這樣使用:

 var stringContents = await file.readAsString();

另外,我們還可以一行一行的對文件進行讀取:

Future<List<String>> readAsLines({Encoding encoding: utf8});

結果返回的是一個List,list中表示文件每行的內容。

 var lines = await file.readAsLines();

上面兩個方法是異步的方法,File還提供了兩個同步的方法:

String readAsStringSync({Encoding encoding: utf8});

List<String> readAsLinesSync({Encoding encoding: utf8});

如果文件是二進制,那么可以使用readAsBytes或者同步的方法readAsBytesSync:

Future<Uint8List> readAsBytes();

Uint8List readAsBytesSync();

dart中表示二進制有一個專門的類型叫做Uint8List,他實際上表示的是一個int的List。

還是剛剛的文件,我們看下怎么以二進制的形式進行讀取:

var file = File('file.txt');
var contents = await file.readAsBytes();

以流的形式讀取文件

上面我們講到的讀取方式,都是一次性讀取整個文件,缺點就是如果文件太大的話,可能造成內存空間的壓力。

所以File為我們提供了另外一種讀取文件的方法,流的形式來讀取文件.

相應的定義方法如下:

  Stream<List<int>> openRead([int? start, int? end]);

我們看一個基本的使用:

import 'dart:io';
import 'dart:convert';

Future<void> main() async {
  var file = File('file.txt');
  Stream<List<int>> inputStream = file.openRead();

  var lines = utf8.decoder
      .bind(inputStream)
      .transform(const LineSplitter());
  try {
    await for (final line in lines) {
      print('Got ${line.length} characters from stream');
    }
    print('file is now closed');
  } catch (e) {
    print(e);
  }
}

隨機訪問

一般情況下文件是順序訪問的,但是有時候我們需要跳過某些前面的數據,直接跳轉到目標地址,則需要對文件進行隨機訪問。

dart提供了open和openSync兩個方法來進行隨機文件讀寫:

  Future<RandomAccessFile> open({FileMode mode: FileMode.read});
  RandomAccessFile openSync({FileMode mode: FileMode.read});

RandomAccessFile提供了對文件的隨機讀寫方法。非常好用。

文件的寫入

寫入和文件讀取一樣,可以一次性寫入或者獲得一個寫入句柄,然后再寫入。

一次性寫入的方法有四種,分別對應字符串和二進制:

 Future<File> writeAsBytes(List<int> bytes,
      {FileMode mode: FileMode.write, bool flush: false});

void writeAsBytesSync(List<int> bytes,
      {FileMode mode: FileMode.write, bool flush: false});

Future<File> writeAsString(String contents,
      {FileMode mode: FileMode.write,
      Encoding encoding: utf8,
      bool flush: false});

void writeAsStringSync(String contents,
      {FileMode mode: FileMode.write,
      Encoding encoding: utf8,
      bool flush: false});

句柄形式可以調用openWrite方法,返回一個IOSink對象,然后通過這個對象進行寫入:

IOSink openWrite({FileMode mode: FileMode.write, Encoding encoding: utf8});
var logFile = File('log.txt');
var sink = logFile.openWrite();
sink.write('FILE ACCESSED ${DateTime.now()}\n');
await sink.flush();
await sink.close();

默認情況下寫入是會覆蓋整個文件的,但是可以通過下面的方式來更改寫入模式:

var sink = logFile.openWrite(mode: FileMode.append);

處理異常

雖然dart中所有的異常都是運行時異常,但是和java一樣,要想手動處理文件讀寫中的異常,則可以使用try,catch:

Future<void> main() async {
  var config = File('config.txt');
  try {
    var contents = await config.readAsString();
    print(contents);
  } catch (e) {
    print(e);
  }
}

總結

以上就是dart中的文件操作了。

本文已收錄於 http://www.flydean.com/23-dart-file/

最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM