Flutter通用IO操作插件universal_io的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter通用IO操作插件universal_io的使用

Overview

universal_io 是一个跨平台的 dart:io 库,它可以在所有平台上工作,包括浏览器。你只需要将 dart:io 的导入替换为 package:universal_io/io.dart 即可。

该库在 Apache License 2.0 下授权。部分源代码源自 Dart SDK,后者是在 Dart SDK 的 BSD 风格许可下获得的。详情请参见 LICENSE 文件。

APIs added on top of “dart:io”

  • newUniversalHttpClient: 返回 BrowserHttpClient 在浏览器上,而在其他平台上返回普通的 dart:io HttpClient。
  • BrowserHttpClient: dart:ioHttpClient 的子类,在浏览器上工作。
  • BrowserHttpClientRequest: dart:ioHttpClientRequest 的子类,在浏览器上工作。
  • BrowserHttpClientResponse: dart:ioHttpClientResponse 的子类,在浏览器上工作。
  • BrowserHttpClientException: 一种异常,帮助理解为什么浏览器上的 HTTP 请求可能失败。

Other features

  • HttpClient: 工厂方法 HttpClient() 在浏览器上返回 BrowserHttpClient
  • Platform: 使 Platform.isAndroidPlatform.isMacOS 等方法在浏览器上也能工作。
  • InternetAddress: 使 InternetAddress 在浏览器上也能工作。
  • BytesBuilder: 使 BytesBuilder 在浏览器上也能工作。

Links

Similar packages

Getting started

1. Add dependency

pubspec.yaml 文件中添加依赖:

dependencies:
  universal_io: ^2.2.2

2. Use HTTP client

下面是一个简单的示例,展示了如何使用 universal_io 进行 HTTP 请求:

import 'package:universal_io/io.dart';

Future<void> main() async {
  // 使用 HttpClient 进行 HTTP 请求
  HttpClient httpClient = newUniversalHttpClient(); // 推荐的创建 HttpClient 的方式
  final request = await httpClient.getUrl(Uri.parse("https://dart.dev/"));
  final response = await request.close();
  
  // 处理响应
  await for (var contents in response.transform(utf8.decoder)) {
    print(contents);
  }
}

HTTP client behavior

HTTP 客户端在浏览器上是通过 XMLHttpRequest (XHR) API 实现的。这导致了一些与 dart:io 不同的行为:

  • HTTP 连接仅在调用 request.close() 后才创建。
  • 存在同源策略限制。对于跨域请求,请参考文档。

Helpful error messages

当请求失败且启用了断言时,错误消息会包含如何修复可能问题(如缺少跨域头)的描述。例如:

XMLHttpRequest error.
-------------------------------------------------------------------------------
HTTP method:             PUT
HTTP URL:                http://destination.com/example
Origin:                  http://source.com
Cross-origin:            true
browserCredentialsMode:  false
browserResponseType:     arraybuffer

THE REASON FOR THE XHR ERROR IS UNKNOWN.
(For security reasons, browsers do not explain XHR errors.)

Is the server down? Did the server have an internal error?

Enabling credentials mode would enable use of some HTTP headers in both the
request and the response. For example, credentials mode is required for
sending/receiving cookies. If you think you need to enable 'credentials mode',
do the following:

    final httpClientRequest = ...;
    if (httpClientRequest is BrowserHttpClientRequest) {
      httpClientRequest.browserCredentialsMode = true;
    }

Did the server respond to a cross-origin "preflight" (OPTIONS) request?

Did the server send the following headers?
  * Access-Control-Allow-Origin: http://source.com
    * You can also use wildcard ("*").
    * Always required for cross-origin requests!
  * Access-Control-Allow-Methods: PUT
    * You can also use wildcard ("*").

Streaming text responses

底层的 XMLHttpRequest (XHR) API 仅在 responseType 为 “text” 时支持响应流式传输。此包根据 HTTP 请求头 “Accept” 的值自动使用 responseType “text”。这些媒体类型定义如下:

  • “text/*”(任何文本媒体类型)
  • “application/grpc-web”
  • “application/grpc-web+proto”

如果你想要禁用流式传输,可以使用以下模式:

Future<void> main() async {
  final client = newUniversalHttpClient();
  if (client is BrowserHttpClient) {
    client.textMimes = const {};
  }
  // ...
}

示例代码

下面是一个完整的示例代码,展示了如何使用 universal_io 进行 HTTP 请求并处理响应:

import 'package:universal_io/io.dart';

void main() async {
  // 使用 'dart:io' HttpClient API
  final httpClient = HttpClient();
  final request = await httpClient.getUrl(Uri.parse('https://dart.dev'));
  final response = await request.close();
  
  // 处理响应内容
  await for (var contents in response.transform(utf8.decoder)) {
    print(contents);
  }
}

希望这些信息能帮助你在 Flutter 项目中更好地使用 universal_io 插件!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter通用IO操作插件universal_io的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter通用IO操作插件universal_io的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用universal_io插件进行通用IO操作的代码示例。universal_io插件允许你在Flutter应用中执行文件读写等IO操作,同时支持Dart VM和Flutter平台(如Android、iOS、Web等)。

首先,确保你已经在pubspec.yaml文件中添加了universal_io依赖:

dependencies:
  flutter:
    sdk: flutter
  universal_io: ^x.y.z  # 替换为最新版本号

然后运行flutter pub get来安装依赖。

以下是一个简单的示例,展示如何使用universal_io插件在Flutter应用中读写文件:

import 'package:flutter/material.dart';
import 'package:universal_io/io.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Universal IO Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () async {
                  await writeFileExample();
                },
                child: Text('Write to File'),
              ),
              ElevatedButton(
                onPressed: () async {
                  await readFileExample();
                },
                child: Text('Read from File'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Future<void> writeFileExample() async {
  // 获取应用的文档目录
  final directory = await getApplicationDocumentsDirectory();
  final filePath = '${directory.path}/example.txt';

  // 要写入的内容
  final content = 'Hello, Universal IO!';

  // 写入文件
  try {
    await File(filePath).writeAsString(content);
    print('File written successfully!');
  } catch (e) {
    print('Failed to write file: $e');
  }
}

Future<void> readFileExample() async {
  // 获取应用的文档目录
  final directory = await getApplicationDocumentsDirectory();
  final filePath = '${directory.path}/example.txt';

  // 读取文件内容
  try {
    final content = await File(filePath).readAsString();
    print('File content: $content');
  } catch (e) {
    print('Failed to read file: $e');
  }
}

代码说明:

  1. 导入必要的包

    • package:flutter/material.dart:用于构建Flutter UI。
    • package:universal_io/io.dart:用于IO操作。
  2. 主函数

    • runApp(MyApp()):启动Flutter应用。
  3. MyApp类

    • 构建一个包含两个按钮的简单UI,一个用于写入文件,另一个用于读取文件。
  4. writeFileExample函数

    • 使用getApplicationDocumentsDirectory获取应用的文档目录。
    • 构建文件路径。
    • 使用File(filePath).writeAsString(content)将字符串写入文件。
  5. readFileExample函数

    • 同样使用getApplicationDocumentsDirectory获取应用的文档目录。
    • 构建文件路径。
    • 使用File(filePath).readAsString()读取文件内容。

通过这些步骤,你可以在Flutter应用中轻松地使用universal_io插件进行文件读写操作。确保在实际项目中处理错误和异常情况,以提供更好的用户体验。

回到顶部