dart:io
dart:io
库([https://api.dart.dev/dart-io/dart-io-library.html])提供用于处理文件、目录、进程、套接字、WebSocket 以及 HTTP 客户端和服务器的 API。
通常情况下, dart:io
库实现并推广异步 API。同步方法很容易阻塞应用程序,使其难以扩展。因此,大多数操作通过Future或Stream对象返回结果,这在Node.js等现代服务器平台中很常见。
dart:io
库中为数不多的同步方法在其方法名称中都清楚地标有Sync后缀。此处不介绍同步方法。
要使用 dart:io
库,必须导入它:
import 'dart:io';
文件和目录
#I/O 库使命令行应用程序能够读取和写入文件以及浏览目录。读取文件内容有两种选择:一次性读取全部内容或流式读取。一次性读取文件需要足够的内存来存储文件的全部内容。如果文件非常大,或者您想在读取文件的同时处理它,则应使用流,如 流式读取文件内容 中所述。
读取文件为文本
#读取使用 UTF-8 编码的文本文件时,可以使用 readAsString()
读取整个文件内容。当各个行很重要时,可以使用 readAsLines()
。在这两种情况下,都会返回一个 Future 对象,该对象将文件的内容作为一个或多个字符串提供。
void main() async {
var config = File('config.txt');
// 将整个文件放入单个字符串中。
var stringContents = await config.readAsString();
print('该文件长度为 ${stringContents.length} 个字符。');
// 将文件的每一行放入其自己的字符串中。
var lines = await config.readAsLines();
print('该文件有 ${lines.length} 行。');
}
读取文件为二进制
#以下代码将整个文件作为字节读取到整数列表中。对 readAsBytes()
的调用返回一个 Future,该 Future 在结果可用时提供结果。
void main() async {
var config = File('config.txt');
var contents = await config.readAsBytes();
print('该文件长度为 ${contents.length} 个字节。');
}
处理错误
#为了捕获错误,以免导致未捕获的异常,可以在 Future 上注册 catchError
处理程序,或者(在 async
函数中)使用 try-catch:
void main() async {
var config = File('config.txt');
try {
var contents = await config.readAsString();
print(contents);
} catch (e) {
print(e);
}
}
流式读取文件内容
#使用流来逐小部分读取文件。您可以使用 Stream API 或 await for
(Dart 的 异步支持 的一部分)。
import 'dart:io';
import 'dart:convert';
void main() async {
var config = File('config.txt');
Stream<List<int>> inputStream = config.openRead();
var lines = utf8.decoder.bind(inputStream).transform(const LineSplitter());
try {
await for (final line in lines) {
print('从流中获取了 ${line.length} 个字符');
}
print('文件现已关闭');
} catch (e) {
print(e);
}
}
写入文件内容
#可以使用 IOSink 将数据写入文件。使用 File 的 openWrite()
方法获取可以写入的 IOSink。默认模式 FileMode.write
会完全覆盖文件中已有的数据。
var logFile = File('log.txt');
var sink = logFile.openWrite();
sink.write('FILE ACCESSED ${DateTime.now()}\n');
await sink.flush();
await sink.close();
要添加到文件的末尾,可以使用可选的 mode
参数指定 FileMode.append
:
var sink = logFile.openWrite(mode: FileMode.append);
要写入二进制数据,请使用 add(List<int> data)
。
列出目录中的文件
#查找目录的所有文件和子目录是一个异步操作。 list()
方法返回一个 Stream,该 Stream 在遇到文件或目录时发出一个对象。
void main() async {
var dir = Directory('tmp');
try {
var dirList = dir.list();
await for (final FileSystemEntity f in dirList) {
if (f is File) {
print('找到文件 ${f.path}');
} else if (f is Directory) {
print('找到目录 ${f.path}');
}
}
} catch (e) {
print(e.toString());
}
}
其他常用功能
#File 和 Directory 类包含其他功能,包括但不限于:
- 创建文件或目录:File 和 Directory 中的
create()
- 删除文件或目录:File 和 Directory 中的
delete()
- 获取文件长度:File 中的
length()
- 获取文件的随机访问:File 中的
open()
有关方法的完整列表,请参阅 File 和 Directory 的 API 文档。
HTTP 客户端和服务器
#dart:io
库提供命令行应用程序可以用来访问 HTTP 资源以及运行 HTTP 服务器的类。
HTTP 服务器
#HttpServer 类提供用于构建 Web 服务器的低级功能。您可以匹配请求处理程序、设置标头、流式传输数据等等。
以下示例 Web 服务器返回简单的文本信息。此服务器监听端口 8888 和地址 127.0.0.1 (localhost),响应对路径 /dart
的请求。对于任何其他路径,响应都是状态代码 404(未找到页面)。
void main() async {
final requests = await HttpServer.bind('localhost', 8888);
await for (final request in requests) {
processRequest(request);
}
}
void processRequest(HttpRequest request) {
print('收到对 ${request.uri.path} 的请求');
final response = request.response;
if (request.uri.path == '/dart') {
response
..headers.contentType = ContentType(
'text',
'plain',
)
..write('Hello from the server');
} else {
response.statusCode = HttpStatus.notFound;
}
response.close();
}
HTTP 客户端
#应避免直接使用 dart:io
发出 HTTP 请求。 dart:io
中的 HttpClient 类依赖于平台,并与单个实现绑定。相反,请使用更高级别的库,例如 package:http
。
从互联网获取数据 教程说明了如何使用 package:http
发出 HTTP 请求。
更多信息
#此页面展示了如何使用 dart:io 库的主要功能。除了本节中讨论的 API 外, dart:io
库还提供用于 进程 、 套接字 和 WebSocket 的 API。有关服务器端和命令行应用程序开发的更多信息,请参阅 服务器端 Dart 概述 。
除非另有说明,否则本网站上的文档反映的是 Dart 3.6.0。页面最后更新于 2025-02-05。 查看源代码 或 报告问题.