標準輸入輸出流
stdin
stdout
stderr
// 匯入io包
import 'dart:io';
void main() {
// 向標準輸出流寫字串
stdout.write('root\$:');
// 從標準輸入流讀取一行字串
var input = stdin.readLineSync();
// 帶換行符的寫資料
stdout.writeln("input data:$input");
// 向標準錯誤流寫資料
stderr.writeln("has not error");
}
複製程式碼
stdin
除了可以使用readLineSync
讀一行字串,還可以使用readByteSync
讀取一個位元組。
檔案操作
寫檔案
一種簡便的操作方式,無需手動關閉檔案,檔案寫入完成後會自動關閉
import 'dart:io';
void main() async{
// 建立檔案
File file = new File('test.txt');
String content = 'The easiest way to write text to a file is to create a File';
try {
// 向檔案寫入字串
await file.writeAsString(content);
print('Data written.');
} catch (e) {
print(e);
}
}
複製程式碼
writeAsString
原型
Future<File> writeAsString(String contents,
{FileMode mode: FileMode.write,
Encoding encoding: utf8,
bool flush: false})
複製程式碼
mode
檔案模式,這裡預設為寫模式encoding
字元編碼,預設為utf-8flush
是否立刻重新整理快取,預設為false
檔案模式FileMode
的常量
常量值 | 說明 |
---|---|
read | 只讀模式 |
write | 可讀可寫模式,如果檔案存在則會覆蓋 |
append | 追加模式,可讀可寫,檔案存在則往末尾追加 |
writeOnly | 只寫模式 |
writeOnlyAppend | 只寫模式下的追加模式,不可讀 |
除了writeAsString
方法外,還可以使用writeAsBytes
寫入一個位元組列表。需要注意的是,這兩個方法都是非同步執行的,返回值都是Future
,如果有必要,也可以使用同步方法執行寫入操作
writeAsStringSync
writeAsBytesSync
如需要更靈活的控制,可以使用如下方式操作檔案,但是需要手動關閉檔案
import 'dart:io';
void main() async{
// 建立檔案
File file = new File('test.txt');
// 檔案模式設定為追加
IOSink isk = file.openWrite(mode: FileMode.append);
// 多次寫入
isk.write('A woman is like a tea bag');
isk.writeln('you never know how strong it is until it\'s in hot water.');
isk.writeln('-Eleanor Roosevelt');
await isk.close();
print('Done!');
}
複製程式碼
讀檔案
簡便的方式
readAsBytes
readAsBytesSync
readAsString
readAsStringSync
readAsLines
readAsLinesSync
void main() async{
File file = new File('test.txt');
try{
String content = await file.readAsString();
print(content);
}catch(e){
print(e);
}
}
複製程式碼
另一種更低階別的方式
import 'dart:io';
import 'dart:convert';
void main() async{
try {
// LineSplitter Dart語言封裝的換行符,此處將文字按行分割
Stream lines = new File('test.txt').openRead()
.transform(utf8.decoder).transform(const LineSplitter());
await for (var line in lines) {
print(line);
}
} catch (_) {}
}
複製程式碼
檔案的其他操作
import 'dart:io';
void main() async{
File file = new File('test.txt');
// 判斷檔案是否存在
if(await file.exists()){
print("檔案存在");
}else{
print("檔案不存在");
}
// 複製檔案
await file.copy("test-1.txt");
// 修改檔名。當傳入不同路徑時,可用來移動檔案
await file.rename("test-2.txt");
// 獲取檔案 size
print(await file.length());
}
複製程式碼
相應的,這些方法還有一個帶Sync
字尾的同步版本方法,例如copySync
、renameSync
等。
要獲取檔案更多的資訊,還可以使用File
等多個類的超類FileSystemEntity
來操作
import 'dart:io';
void main() async{
String path = 'test.txt';
// 判斷路徑是否是資料夾
if (!await FileSystemEntity.isDirectory(path)) {
print('$path is not a directory');
}
Directory dir = Directory(r'D:\workspace\dart_space\Tutorial');
// 目錄是否存在
if(await dir.exists()){
// 從目錄的list方法獲取FileSystemEntity物件
Stream<FileSystemEntity> fse = await dir.list();
await for (FileSystemEntity entity in fse) {
if(entity is File){
print("entity is file");
}
// 列印檔案資訊
print(await entity.stat());
// 刪除
await entity.delete();
}
}else{
// 不存在則建立。recursive為true時,建立路徑上所有不存在的目錄
await dir.create(recursive: true);
}
}
複製程式碼
需注意,delete
中包含一個可選的引數,原型Future<FileSystemEntity> delete({bool recursive: false})
,recursive
預設為false,當刪除目錄時,目錄必須為空才能刪除;當recursive
設定為true時,將刪除目錄下的所有子目錄及檔案。