flutter 文件的操作

import 'dart:io';
import 'package:flutter_document_picker/flutter_document_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:smartphone/util/date_util.dart';
import 'logger_util.dart';

/// File manager
class FileUtil {
  /// フォルダ名
  static String fileName = "file";

  /// 経路
  static String _temporaryDirectory = "";

  /// @description フォルダの作成
  /// @return void
  static void createCounter() {
    getTemporaryDirectory().then((value) {
      _temporaryDirectory = value.path;
      Directory directory = Directory('$_temporaryDirectory/$fileName');
      if (!directory.existsSync()) {
        directory.createSync();
        logD('ドキュメントの初期化に成功しました。ファイルの保存パスは ${directory.path}');
      }
    });
  }

  /// @description ファイルストレージパスの作成
  /// @return Future<String>
  static Future<String> createLogCounter() {
    var name = DateUtil.getDateTime(DateTime.now().millisecondsSinceEpoch, DateType.yyyymmddNoSplit);
    return getTemporaryDirectory().then((value) {
      _temporaryDirectory = value.path;
      Directory directory = Directory('$_temporaryDirectory/$name');
      if (!directory.existsSync()) {
        directory.createSync();
        logD('ドキュメントの初期化に成功しました。ファイルの保存パスは ${directory.path}');
      }
      return directory.path;
    });
  }

  /// @description 内容を書く
  /// @param: contents 内容を書く
  /// @param: name 書類名.
  /// @return void
  static void writeCounter(String contents, String name) {
    File file = File('$_temporaryDirectory/$fileName/$name');
    String counterString = "";
    if ( file.existsSync() ) {
      counterString = file.readAsStringSync();
    }
    String resultString = counterString + contents;
    // 上書き書き
    file.writeAsString(resultString).then((value) {
      logWTF(value.path);
    });
  }

  /// @description 日誌を書き始める
  /// @param: contents 内容を書く
  /// @return void
  static void writeLog(String contents) async {
    var path = await createLogCounter();
    if (path.isEmpty) {
      logE('path is null');
      return;
    }

    String counterString = '';
    var name = DateUtil.getDateTime(DateTime.now().millisecondsSinceEpoch, DateType.yyyymmddNoSplit);
    File file;
    for (var i = 1; ; i++) {
      file = File('$path/errorlog_${name}_$i.txt');
      if (file.existsSync()) {
        if (file.lengthSync() < 10 * 1024 * 1024) {
          counterString = file.readAsStringSync();
          break;
        }
      } else {
        break;
      }
    }
    String resultString = counterString + contents;
    // 上書き書き
    file.writeAsString(resultString).then((value) {
      logWTF(value.path);
    });
  }

  /// @description ファイルの取得
  /// @param: name 書類名.
  /// @return File
  static File getLocalFile(String name) {
    return File("$_temporaryDirectory/$fileName/$name");
  }

  /// @description 読み取りコンテンツ長
  /// @param: name 書類名.
  /// @return int
  static int readCounter(String name) {
    try {
      File file = getLocalFile(name);
      // テキストコンテンツの読み取り
      String counterString = file.readAsStringSync();
      return int.parse(counterString);
    } on FileSystemException {
      return 0;
    }
  }

  /// @description ローカルファイル選択ダイログ表示
  /// @return Future<File?> 選択されだファイル
  static Future<File?> getLocalDocumentFile() async {
    final path = await FlutterDocumentPicker.openDocument();
    if (path != null) {
      var file = File(path);
      // ファイル名称を取得する
      String tgzName = file.toString().split("/").last;
      // サンドボックスのパース+file+ファイル名称
      file = await file.rename('$_temporaryDirectory/$fileName/$tgzName');
      return file;
    }
    return null;
  }

  /// @description コンテンツの削除
  /// @return void
  static void deleteCounter() {
    Directory directory = Directory('$_temporaryDirectory/$fileName');
    if (directory.existsSync()) {
      List<FileSystemEntity> files = directory.listSync();
      if (files.isNotEmpty) {
        for (var file in files) {
          // ファイルのFW更新.tgzを削除する
          file.deleteSync();
        }
      }
      // ファイルを削除する
      // directory.deleteSync();
    }
  }

  /// @description 最新のログファイルを取得する
  /// @return File?
  static File? getNewestLogFile() {
    try {
      Directory directory = Directory(_temporaryDirectory);
      var directoryList = directory.listSync();
      directoryList = directoryList.where((element) {
        var name = element.path.split('/').last;
        return int.tryParse(name) != null;
      }).toList();
      var newestDirectory = directoryList.reduce((current, next) {
        var currentName = int.parse(current.path.split('/').last);
        var nextName = int.parse(next.path.split('/').last);
        return currentName > nextName ? current : next;
      });
      directory = Directory(newestDirectory.path);
      directoryList = directory.listSync();
      var newestFile = directoryList.reduce((current, next) {
        // /data/user/0/com.xxx.worker.worker/cache/2023529/errorlog_2023529_1.txt
        var currentIndex = current.path.split('/').last // errorlog_2023529_1.txt
            .split('.').first // errorlog_2023529_1
            .split('_').last; // 1
        var nextIndex = next.path.split('/').last
            .split('.').first
            .split('_').last;
        return int.parse(currentIndex) > int.parse(nextIndex) ? current : next;
      });
      logWTF(newestFile.path);
      return newestFile as File;
    } catch (e) {
      return null;
    }
  }

  /// @description すべてのファイルを取得
  /// @return List<FileSystemEntity>?
  static List<FileSystemEntity>? getAllCounter() {
    Directory directory = Directory('$_temporaryDirectory/$fileName');
    return directory.listSync();
  }

  /// @description 最新バージョンに戻る
  /// @return FileSystemEntity?
  static FileSystemEntity? obtainTheLatestVersionInformation() {
    Directory directory = Directory('$_temporaryDirectory/$fileName');
    // ファイル名:E1FW_PKG_vxxx.tgz(xxx:数字 3 桁)
    FileSystemEntity? fileSystemEntity;
    if (directory.existsSync()) {
      List<FileSystemEntity> files = directory.listSync();
      if (files.isNotEmpty) {
        int version = 0;
        for (var file in files) {
          String fileSuffix = file.path.split("E1FW_PKG_v").last;
          if (fileSuffix.isNotEmpty) {
            // ファイル名が E1FW_PKG_vxxx.tgz 以外ならば、FW 更新ファイルとして認識しないこと。
            if (fileSuffix.contains(".tgz")) {
              int fileVersion = int.parse(fileSuffix.split(".").first);
              if (fileVersion > version) {
                version = fileVersion;
                fileSystemEntity = file;
              }
            }
          }
        }
      }
    }
    return fileSystemEntity;
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Flutter 是一个跨平台的移动应用程序开发框架,可以快速构建具备丰富用户界面和功能的应用程序。在Flutter的开发中,文件下载是不可避免的需求,经常遇到需要下载文件的场景,例如下载图片、音频以及视频等媒体文件或其他数据文件Flutter 提供了许多第三方库来实现文件下载,常用的有http、dio等库,这些库都可以配合Flutter的异步特性来下载文件,并提供了丰富的参数设置和进度回调信息。 在使用http库进行文件下载时,可以通过设置请求头信息为字节范围来支持断点续传,即如果下载中断可以继续下载,避免重复下载浪费流量和时间。同时,还可以通过设置连接和读取超时时间等参数来优化下载体验。使用http库下载文件的代码示例如下: ``` import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:io'; import 'dart:async'; class DownloadFile extends StatefulWidget { @override _DownloadFileState createState() => _DownloadFileState(); } class _DownloadFileState extends State<DownloadFile> { String downloadUrl = "http://www.example.com/file.mp3"; String savePath = Directory.systemTemp.path + "/file.mp3"; Future<void> _downloadFile(String url, String savePath) async { final response = await http.get(url, headers: { HttpHeaders.rangeHeader: "bytes=${File(savePath).lengthSync()}-" }).timeout(Duration(seconds: 30)); if (response.statusCode == 200 || response.statusCode == 206) { File(savePath).writeAsBytesSync(response.bodyBytes, mode: FileMode.append); } else { throw Exception("Download failed: ${response.statusCode}"); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Download file example"), ), body: Center( child: RaisedButton( onPressed: () { _downloadFile(downloadUrl, savePath); }, child: Text("Download file"), ), ), ); } } ``` 在上述代码中,使用dio库下载文件也可以实现类似的功能,而且dio库有更加方便的操作和更加详细的错误处理和进度监听功能。需要注意的是,使用dio库需要在pubspec.yaml文件中添加依赖库: ``` dependencies: dio: ^3.0.10 ``` 使用dio库下载文件的代码示例如下: ``` import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; import 'dart:io'; import 'dart:async'; class DownloadFile extends StatefulWidget { @override _DownloadFileState createState() => _DownloadFileState(); } class _DownloadFileState extends State<DownloadFile> { String downloadUrl = "http://www.example.com/file.mp3"; String savePath = Directory.systemTemp.path + "/file.mp3"; Future<void> _downloadFile(String url, String savePath) async { Dio dio = Dio(); try { Response response = await dio.download( url, savePath, onReceiveProgress: (count, total) => print("Received $count bytes out of $total"), options: Options(headers: { HttpHeaders.rangeHeader: "bytes=${File(savePath).lengthSync()}-" }), ); } catch (e) { throw Exception("Download failed: $e"); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Download file example"), ), body: Center( child: RaisedButton( onPressed: () { _downloadFile(downloadUrl, savePath); }, child: Text("Download file"), ), ), ); } } ``` 综上所述,Flutter提供了多种库可以实现文件下载功能,选择合适的库可以有效地提升下载效率和下载体验,进一步提升应用的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值