Flutter 笔记 | Flutter 文件IO、网络请求、JSON、日期与国际化

这篇具有很好参考价值的文章主要介绍了Flutter 笔记 | Flutter 文件IO、网络请求、JSON、日期与国际化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文件IO操作

Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的,不过和 Dart VM 相比,Flutter 有一个重要差异是文件系统路径不同,这是因为 Dart VM 是运行在 PC 或服务器操作系统下,而 Flutter 是运行在移动操作系统中,他们的文件系统会有一些差异。

APP目录

Android 和 iOS 的应用存储目录不同,PathProvider 插件提供了一种平台透明的方式来访问设备文件系统上的常用位置。该类当前支持访问两个文件系统位置:

  • 临时目录: 可以使用 getTemporaryDirectory() 来获取临时目录; 系统可随时清除临时目录的文件。在 iOS 上,这对应于NSTemporaryDirectory() 返回的值。在 Android上,这是getCacheDir() 返回的值。
  • 文档目录: 可以使用getApplicationDocumentsDirectory()来获取应用程序的文档目录,该目录用于存储只有自己可以访问的文件。只有当应用程序被卸载时,系统才会清除该目录。在 iOS 上,这对应于NSDocumentDirectory。在 Android 上,这是AppData目录。
  • 外部存储目录:可以使用getExternalStorageDirectory()来获取外部存储目录,如 SD 卡;由于 iOS不支持外部目录,所以在 iOS 下调用该方法会抛出UnsupportedError异常,而在 Android 下结果是Android SDK 中getExternalStorageDirectory的返回值。

一旦你的 Flutter 应用程序有一个文件位置的引用,你可以使用 dart:io API来执行对文件系统的读/写操作。例如:

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

// Reading a file as text
// When reading a text file encoded using UTF-8,
// you can read the entire file contents with readAsString().
// When the individual lines are important, you can use readAsLines().
// In both cases, a Future object is returned that provides the contents of the
// file as one or more strings.
Future<void> readFileAsText() async {
   
  var config = File('config.txt');

// Put the whole file in a single string.
  var stringContents = await config.readAsString();
  print('The file is ${
     stringContents.length} characters long.');

// Put each line of the file into its own string.
  var lines = await config.readAsLines();
  print('The file is ${
     lines.length} lines long.');
}

// Reading a file as binary
// The following code reads an entire file as bytes into a list of ints.
// The call to readAsBytes() returns a Future, which provides the result when it’s available.
Future<void> readFileAsBinary() async {
   
  var config = File('config.txt');
  var contents = await config.readAsBytes();
  print('The file is ${
     contents.length} bytes long.');
}

// Handling errors
// To capture errors so they don’t result in uncaught exceptions, you can register
// a catchError handler on the Future, or (in an async function) use try-catch:
Future<void> handlingErrors() async {
   
  var config = File('config.txt');
  try {
   
    var contents = await config.readAsString();
    print(contents);
  } catch (e) {
   
    print(e);
  }
}

// Streaming file contents
// Use a Stream to read a file, a little at a time. You can use either the Stream
// API or await for, part of Dart’s asynchrony support.
Future<void> streamingFileContents() 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('Got ${
     line.length} characters from stream');
    }
    print('file is now closed');
  } catch (e) {
   
    print(e);
  }
}

// Writing file contents
// You can use an IOSinklaunch to write data to a file. Use the File openWrite()
// method to get an IOSink that you can write to. The default mode, FileMode.write,
// completely overwrites existing data in the file.
Future<void> writingFileContent() async {
   
  var logFile = File('log.txt');
  var sink = logFile.openWrite();
  sink.write('FILE ACCESSED ${
     DateTime.now()}\n');
  // To add to the end of the file, use the optional mode parameter to specify FileMode.append:
  // var sink = logFile.openWrite(mode: FileMode.append);
  await sink.flush();
  await sink.close();
}

// To write binary data, use add(List<int> data).Listing files in a directory
// Finding all files and subdirectories for a directory is an asynchronous operation.
// The list() method returns a Stream that emits an object when a file or directory is encountered.
Future<void> writeBinaryData() async {
   
  var dir = Directory('tmp');
  try {
   
    var dirList = dir.list();
    await for (final FileSystemEntity f in dirList) {
   
      if (f is File) {
   
        print('Found file ${
     f.path}');
      } else if (f is Directory) {
   
        print('Found dir ${
     f.path}');
      }
    }
  } catch (e) {
   
    print(e.toString());
  }
}

更多有关 Dart 进行文件处理的详细内容可以参考 Dart 语言文档,下面我们看一个简单的例子。

示例

我们还是以计数器为例,实现在应用退出重启后可以恢复点击次数。 这里,我们使用文件来保存数据:

  1. 引入PathProvider插件;在pubspec.yaml文件中添加如下声明:
path_provider: ^2.0.15

添加后,执行 flutter packages get 获取一下, 版本号可能随着时间推移会发生变化,可以使用最新版。

实现:

import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

class FileOperationRoute extends StatefulWidget {
   
  FileOperationRoute({
   Key? key}) : super(key: key);

  
  _FileOperationRouteState createState() => _FileOperationRouteState();
}

class _FileOperationRouteState extends State<FileOperationRoute> {
   
  int _counter = 0;

  
  void initState() {
   
    super.initState();
    // 从文件读取点击次数
    _readCounter().then((int value) {
   
      setState(() {
   
        _counter = value;
      });
    });
  }

  Future<File> _getLocalFile() async {
   
    // 获取应用目录
    String dir = (await getApplicationDocumentsDirectory()).path;
    return File('$dir/counter.txt');
  }

  Future<int> _readCounter() async {
   
    try {
   
      File file = await _getLocalFile();
      // 读取点击次数(以字符串)
      String contents = await file.readAsString();
      return int.parse(contents);
    } on FileSystemException {
   
      return 0;
    }
  }

  _incrementCounter() async {
   
    setState(() {
   
      _counter++;
    });
    // 将点击次数以字符串类型写到文件中
    await (await _getLocalFile()).writeAsString('$_counter');
  }


  
  Widget build(BuildContext context) {
   
    return Scaffold(
      appBar: AppBar(title: Text('文件操作')),
      body: Center(
        child: Text('点击了 $_counter 次'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

上面代码比较简单,不再赘述,需要说明的是,本示例只是为了演示文件读写,而在实际开发中,如果要存储一些简单的数据,使用shared_preferences插件会比较简单。

网络请求

通过HttpClient发起HTTP请求

Dart IO库中提供了用于发起Http请求的一些类,我们可以直接使用HttpClient来发起请求。使用HttpClient发起请求分为五步:

  1. 创建一个HttpClient
 HttpClient httpClient = HttpClient();
  1. 打开Http连接,设置请求头:
HttpClientRequest request = await httpClient.getUrl(uri);

这一步可以使用任意Http Method,如httpClient.post(...)httpClient.delete(...)等。如果包含Query参数,可以在构建uri时添加,如:

Uri uri = Uri(scheme: "https", host: "flutterchina.club", queryParameters: {
   
    "xx":"xx",
    "yy":"dd"
  });

通过HttpClientRequest可以设置请求header,如:

request.headers.add("user-agent", "test");

如果是postput等可以携带请求体方法,可以通过HttpClientRequest对象发送请求体,如:

String payload="...";
request.add(utf8.encode(payload)); 
//request.addStream(_inputStream); //可以直接添加输入流
  1. 等待连接服务器:
HttpClientResponse response = await request.close();

这一步完成后,请求信息就已经发送给服务器了,返回一个HttpClientResponse对象,它包含响应头(header)和响应流(响应体的Stream),接下来就可以通过读取响应流来获取响应内容。

  1. 读取响应内容:
String responseBody = await response.transform(utf8.decoder).join();

我们通过读取响应流来获取服务器返回的数据,在读取时我们可以设置编码格式,这里是utf8

  1. 请求结束,关闭HttpClient
httpClient.close();

关闭client后,通过该client发起的所有请求都会终止。

示例

下面代码实现点击按钮后请求百度首页,请求成功后,将返回内容显示出来并在控制台打印响应header,代码如下:

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

import 'package:flutter/material.dart';

class HttpTestRoute extends StatefulWidget {
   
  
  _HttpTestRouteState createState() => _HttpTestRouteState();
}

class _HttpTestRouteState extends State<HttpTestRoute> {
   
  bool _loading = false;
  String _text = "";

  
  Widget build(BuildContext context) {
   
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          ElevatedButton(
            child: Text("获取百度首页"),
            onPressed: _loading ? null : request,
          ),
          Container(
            width: MediaQuery.of(context).size.width - 50.0,
            child: Text(_text.replaceAll(RegExp(r"\s"), "")),
          )
        ],
      ),
    );
  }

  request() async {
   
    setState(() {
   
      _loading = true;
      _text = "正在请求...";
    });
    try {
   
      //创建一个HttpClient
      HttpClient httpClient = HttpClient();
      //打开Http连接
      HttpClientRequest request =
          await httpClient.getUrl(Uri.parse("https://www.baidu.com"));
      //使用iPhone的UA
      request.headers.add(
        "user-agent",
        "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1",
      );
      //等待连接服务器(会将请求信息发送给服务器)
      HttpClientResponse response = await request.close();
      //读取响应内容
      _text = await response.transform(utf8.decoder).join();
      //输出响应头
      print(response.headers);

      //关闭client后,通过该client发起的所有请求都会终止。
      httpClient.close();
    } catch (e) {
   
      _text = "请求失败:$e";
    } finally {
   
      setState(() {
   
        _loading = false;
      });
    }
  }
}

控制台输出:文章来源地址https://www.toymoban.com/news/detail-468114.html

I/flutter (18545): connection: Keep-Alive
I/flutter (18545): cache-control: no-cache
I/flutter (18545): set-cookie: ....  //有多个,省略...
I/flutter (18545): transfer-encoding: chunked
I/flutter (18545): date: Tue, 30 Oct 2018 10:00:52 GMT
I/flutter (18545): content-encoding: gzip
I/flutter (18545): vary: Accept-Encoding
I/flutter (18545): strict-transport-security: max-age=172800
I/flutter (18545): content-type: text/html;charset=utf-8
I/flutter (18545): tracecode: 0052526240106576129010301

到了这里,关于Flutter 笔记 | Flutter 文件IO、网络请求、JSON、日期与国际化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter GetX 之 国际化

    今天给大家介绍一下 GetX 的国际化功能,在日常开发过程中,我们经常会使用到国际化功能,需要们的应用支持 国际化,例如我们需要支持 简体、繁体、英文等等。 上几篇文章介绍了GetX的 路由管理 和 状态管理,看到大家的点赞和收藏,还是很开心的,说明这两篇文章给大

    2024年01月19日
    浏览(46)
  • 【国际化Intl】Flutter 国际化多语言实践

    提示:这里参考一下几个链接 例如: https://github.com/ThinkerWing/language https://juejin.cn/post/6844903823119482888 这篇也很详细,还有包括兼容中文的繁体简体… 可以看看 该分支对应的提交是使用Android Studio 和 Flutter Intl插件 并根据掘金这篇文章的实践,兼容汉字简体和繁体字 https://g

    2023年04月23日
    浏览(46)
  • Flutter之国际化(多语言处理)

    项目内最近加入国际化内容,那么我们需要转化对应语言内容,来展示UI App国际化开发主要包括: 文本国际化 Widget显示的国际化 某些文本在对应语言环境下应该显示为所选择语言内容; 目前我项目内使用的是: Flutter Intl 插件: 1.安装 Flutter Intl 插件 在Android studio内直接搜

    2024年02月14日
    浏览(36)
  • 【100天精通python】Day28:文件与IO操作_JSON文件处理

      目录   专栏导读  1. JSON数据格式简介 1.1 示例JSON数据 1.2 JSON文件的特点 

    2024年02月14日
    浏览(40)
  • Flutter中的http网络请求

    } 以上代码中httpClient.getUrl(uri)方法即是根据uri发起get请求,post请求用法和get请求只是调用方法不同,包括参数设置等其他用法都一样。请求抓包结果如下: get请求 post请求 请求成功之后以上代码输出结果如下: I/flutter (19183): 请求成功 I/flutter (19183): responseBody={“resultcode”

    2024年04月16日
    浏览(18)
  • Android Studio快速实现Flutter应用的国际化和多语言支持

    在Flutter中实现国际化和多语言支持通常涉及以下步骤: 首先,你需要添加flutter_localizations依赖库到你的pubspec.yaml文件中。这个库包含了Flutter国际化所需的核心功能。 Android Studio菜单File-Settings-Plugins(直接搜索效率菜单效率更高) 安装Flutter Intl插件后重启Android Studio 插件安装

    2024年02月08日
    浏览(29)
  • Flutter网络请求框架Dio源码分析以及封装(一)--请求流程分析

    利用flutter开发app也已经有些时间了,这个过程中最多接触到的就是网络请求相关的代码。自己目前项目中使用的是现在市面上最流行的网络请求库-dio,相对于flutter自带的HttpClient来说,dio使用起来更简单,功能更强大,支持全局配置、Restful API、FormData、拦截器、 请求取消、

    2024年02月09日
    浏览(29)
  • Flutter中的http网络请求,值得一看

    本篇介绍Flutter中网络请求相关api的使用,Flutter在Flutter engine中提供了一个sky_engine开发工具包,其包含了一个_http的库,该库中有封装的http请求相关的各种操作类。本文我们将介绍_http相关操作类的使用和基于_http封装的三方dio网络库的使用。 _http库中的http.dart文件中封装的

    2024年04月11日
    浏览(25)
  • uniapp配置了pages.json 的 tabbar 国际化,小程序切换语言没有实时切换

    如上图,按照uniapp官方文档配置了tabbar的国际化 但是微信小程序实时切换语言没有实时刷新 解决方案: 在App.vue中加入以下代码:   在onLaunch中执行方法即可

    2024年04月28日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包