文件IO模块

Dart提供的IO相关API,使用起来非常简洁,跟NodeJS不相上下。

  • 文件和目录的创建与删除

    //创建文件
    var file = File("abc.txt");
    file.createSync(recursive: true); //recursive表示递归创建,如果你传的路径包含不存在的目录,会一同创建
      //创建目录
    var dir = Directory("aaa");
    dir.createSync(recursive: true);
    

    从方法名字也能看出是同步创建,Dart也提供了异步创建的API,比如:

    main() async{
      await File("abc.txt").create(recursive: true);
      await Directory("aaa").create(recursive: true);
      await file.delete(recursive: true);//删除文件
      await dir.deleteSync(recursive: true);//递归删除目录   
    }
    

    下面文件相关的很多API都提供了同步和异步的方法,我只演示异步的用法。

  • 遍历目录

    await Directory("aaa").list(recursive: true).forEach((entry) async{
        var stat = await entry.stat();
        print("path: ${entry.path} lastModify: ${stat.modified}");
    });
    //输出
    path: aaa\a.txt lastModify: 2019-04-30 22:27:07.000
    path: aaa\b.txt lastModify: 2019-04-30 22:27:07.000
    path: aaa\c.txt lastModify: 2019-04-30 22:27:07.000
    
  • 文件读写

    print((await file.readAsString())); //读取文件的全部内容,默认是utf8编码
    print((await file.readAsBytes())); //读取文件的全部字节
    (await file.readAsLines()).forEach((el) => print(el) ); //读取全部行
    print((await file.writeAsString("aaaaa", mode: FileMode.append)));
    

    如果文件比较大,就只能以流的方式读取:

    var f = await file.open();
    var buffer = List<int>(15);
    var total = await file.length();
    var len = 0;
    while(len < total){
        len += await f.readInto(buffer);
        print("len: $len  total: $total");
    }
    //也可以使用遍历Stream的方式
    await for (var bytes in file.openRead()){
        print(bytes);
    }
    
  • 其他

    //是否是绝对路径,并不要求路径的文件或目录一定存在
    print(File("abc.txt").isAbsolute);//false
    print(File("c:/abc.txt").isAbsolute);//true
    print(file.absolute.path); //获取绝对路径
    
    print("文件大小:${await file.length()}");//文件大小
    print("文件大小:${await file.lastModified()}");//上次访问时间
    await file.copy("abc-copy.txt"); //拷贝文件
    await File("abc-copy.txt").rename("abc-copy2.txt");//重命名
    

Uri模块

Uri类主要提供了对Url的编码解码,解析和组装的功能。

为什么要对Url进行编码?

对Url进行编码主要是避免Url中包含特殊字符,比如&;&在Url中有特殊含义,如果你就像通过Url传输&,就会引起歧义,因此需要对Url进行编码和解码。

对url特殊字符进行解码和编码:

var url = "https://lixiaojun.xin?name=&哥哥&&nickname=#  #";
var encodeUrl = Uri.encodeFull(url);
print(encodeUrl);//https://lixiaojun.xin?name=&%E5%93%A5%E5%93%A5&&nickname=#%20%20#
print(Uri.decodeFull(encodeUrl));//https://lixiaojun.xin?name=&哥哥&&nickname=#  #

Uri.encodeFullUri.decodeFull只会对Url的参数部分进行编码解码,如果想对整个Url进行编解码,需要使用Uri.encodeComponentUri.decodeComponent

encodeUrl = Uri.encodeComponent(url);
print(encodeUrl);//https%3A%2F%2Flixiaojun.xin%3Fname%3D%26%E5%93%A5%E5%93%A5%26%26nickname%3D%23%20%20%23
print(Uri.decodeComponent(encodeUrl));//https://lixiaojun.xin?name=&哥哥&&nickname=#  #

Uri类还可以解析出Url的各个部分:

var uri = Uri.parse("https://lixiaojun.xin:80/courses/dart?name=lxj");
print("schema: ${uri.scheme} host: ${uri.host} path: ${uri.path}  query param: ${uri.query}");
//schema: https host: lixiaojun.xin path: /courses/dart  query param: name=lxj

日期与时间

日期与时间的处理在开发中一定会遇到,Dart提供了丰富的方法来处理时间。

获取时间相关:

print(DateTime.now());//获取当前时间,字符串形式
print(DateTime.now().millisecondsSinceEpoch);//获取当前时间戳,单位毫秒
print(DateTime.now().year);//年份
print(DateTime.now().month);//几月
print(DateTime.now().day);//当月第几天

创建时间:

print(DateTime(2011, 2, 2));//创建时间

转换相关:

print(DateTime.parse("2013-02-27 13:27:00"));//字符串转时间,但有格式要求
print(DateTime.tryParse("2013-2-27"));//格式出错,返回null
print(DateTime.fromMillisecondsSinceEpoch(1556272606285));//时间戳转日期

其他操作:

print(DateTime.now().subtract(Duration(days: 1)));//往前减去1天
print(DateTime.now().add(Duration(days: 1))); //往后加1天
print(DateTime.now().isAfter(DateTime.parse("2013-02-27 13:27:00")));//日期前后比较

Json编解码

Dart提供了用于对Json进行编解码的方法。

var json = '''
  [
    {"name": "lxj", "age": 22 },
    {"name": "wsc", "age": 21 }
  ]
  ''';
print(jsonDecode(json));//[{name: lxj, age: 22}, {name: wsc, age: 21}]
var map = {
    "address": '武汉',
    'name': 'lxj'
};
print(jsonEncode(map));//{"address":"武汉","name":"lxj"}

上面的方法是将Json和集合之间相互转换,实际开发中很多是Json与模型类之间相互转换,定义一个模型类:

class User{
  String name, address;
  User(this.name, this.address);
}

对模型类进行编码:

print(jsonEncode(User("aaa", "武汉")));

结果发现报异常,对于模型类和Json相互转换,Dart要求模型类提供两个方法fromJsontoJson,才能进行转换。对代码进行更改:

class User{
  String name, address;
  User(this.name, this.address);
  //Json转模型类用到  
  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        address = json['address'];
  //模型类转Json用到
  Map<String, dynamic> toJson() =>
      {
        'name': name,
        'address': address,
      };
}

将Json解码为模型类:

print(User.fromJson(jsonDecode('''
    {
    "address": "武汉",
    "name": "lxj"
    }
  ''')));

实际项目中,如果给每个模型类都添加fromJsontoJson方法还是挺麻烦的,可以用Dart的一些三方包去简化代码,这里只演示标准库的用法。

更新时间: 5/6/2019, 11:32:40 AM