Flutter文件扩展名处理插件file_ext的使用

Flutter文件扩展名处理插件file_ext的使用

特性

该插件提供了异步和同步扩展方法来:

  • 循环遍历文件系统实体(通过多个目录中的多个Glob模式过滤)并调用用户定义的函数。
  • 循环遍历所有基于内存的文件系统,并调用用户定义的函数(适用于单元测试)。
  • 循环遍历来自标准输入的行并调用用户定义的函数或读取整个标准输入。
  • 文件路径API扩展:
    • adjust() - 将所有路径分隔符转换为操作系统特定的样式。
    • toPosix() - 将所有路径分隔符转换为POSIX样式。
    • getFullPath() - 类似于canonicalize(),但保留字母大小写。
    • isHidden() - 检查给定文件名是否以点开始,或者路径是否包含以点开始的子目录(但不仅限于点)。
    • isPath() - 检查给定字符串是否包含目录组件。

使用

请参见下面的示例代码。所有示例代码文件都在example子目录下。

// Copyright (c) 2022-2023, Alexander Iurovetski
// All rights reserved under MIT license (see LICENSE file)

import 'dart:io';

import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:file_ext/file_ext.dart';
import 'package:glob/glob.dart';
import 'package:intl/intl.dart';
import 'package:loop_visitor/loop_visitor.dart';
import 'package:parse_args/parse_args.dart';
import 'package:thin_logger/thin_logger.dart';

/// A type for the argument parsing callback functions
///
typedef ParseArgsHandler = void Function(String);

/// Application
///
class Options {
  static const appName = 'file_ext_example';

  /// Count findings only
  ///
  var isCountOnly = false;

  /// Synchronous call flag
  ///
  var isSync = false;

  /// Logger
  ///
  final Logger logger = Logger();

  /// FileSystem
  ///
  final FileSystem fileSystem;

  /// All filters
  ///
  final List<Glob> filters = [];

  /// FileList flags
  ///
  var flags = 0;

  /// Directory to start in
  ///
  final List<String> roots = [];

  /// Entity types to consider
  ///
  final List<FileSystemEntityType> types = [];

  /// The actual usage
  ///
  Options(this.fileSystem);

  void parse(List<String> args) {
    var optDefs = '''
      |?,h,help|q,quiet|v,verbose|a,all|d,dir::
      |c,count|L,follow|s,sync|t,type:|::?
    ''';

    var opts = parseArgs(optDefs, args);
    logger.levelFromFlags(isQuiet: opts.isSet('q'), isVerbose: opts.isSet('v'));

    if (opts.isSet('?')) {
      printUsage();
    }

    isCountOnly = opts.isSet('c');
    isSync = opts.isSet('s');

    flags = 0;

    if (!opts.isSet('L')) {
      flags |= FileSystemExt.followLinks;
    }

    if (opts.isSet('a')) {
      flags |= FileSystemExt.allowHidden;
    }

    final typeStr = opts.getStrValue('t')?.toLowerCase();

    if ((typeStr == null) || typeStr.isEmpty || typeStr.contains('d')) {
      types.add(FileSystemEntityType.directory);
    }

    if ((typeStr == null) || typeStr.isEmpty || typeStr.contains('f')) {
      types.add(FileSystemEntityType.file);
    }

    if ((typeStr == null) || typeStr.isEmpty || typeStr.contains('l')) {
      types.add(FileSystemEntityType.link);
    }

    roots.addAll(opts.getStrValues('d'));
    filters.addAll(opts.getGlobValues(''));
  }
}

/// Application singleton
///
final Options opt = Options(LocalFileSystem());

/// Run single filter
///
Never printUsage() {
  opt.logger.info('''
USAGE:

${Options.appName} [OPTIONS]

OPTIONS:

-d, dir DIR   - directory to start in (default: current)
-c,count      - print count only
-L,follow     - expand symbolic links
-s,sync       - fetch synchronously (blocking mode)
-t,type TYPES - entries to fetch (default - all):
                d - directory
                f - file
                l - link
ARGUMENTS:

One or more glob patterns

EXAMPLES:

${Options.appName} -d /home/user/Downloads -type f ../Documents/**.{doc,docx} *.txt
''');

  exit(1);
}

/// Entry point
///
void main(List<String> args) async {
  opt.parse(args);

  var count = 0;

  if (opt.isSync) {
    opt.fileSystem.forEachEntitySync(
        roots: opt.roots,
        filters: opt.filters,
        flags: opt.flags,
        types: opt.types,
        onEntity: (fileSystem, entity, stat) {
          if ((entity == null) || (stat == null)) {
            return VisitResult.take; // continue
          }
          if (opt.isCountOnly) {
            ++count;
          } else {
            var path = fileSystem.path.adjustTrailingSeparator(
                entity.path, stat.type,
                isAppend: true);
            if (stat.type == FileSystemEntityType.link) {
              path += ' -> ${fileSystem.file(path).resolveSymbolicLinksSync()}';
            }
            opt.logger.out(path);
          }
          return VisitResult.take; // continue
        },
        onException: (fileSystem, entity, stat, exception, stackTrace) {
          opt.logger.error(exception.toString());
          return VisitResult.take; // continue
        });
  } else {
    await opt.fileSystem.forEachEntity(
        roots: opt.roots,
        filters: opt.filters,
        flags: opt.flags,
        types: opt.types,
        onEntity: (fileSystem, entity, stat) async {
          if ((entity == null) || (stat == null)) {
            return VisitResult.take; // continue
          }
          if (opt.isCountOnly) {
            ++count;
          } else {
            var path = opt.fileSystem.path.adjustTrailingSeparator(
                entity.path, stat.type,
                isAppend: true);
            if (stat.type == FileSystemEntityType.link) {
              path += ' -> ${fileSystem.file(path).resolveSymbolicLinksSync()}';
            }
            opt.logger.out(path);
          }
          return VisitResult.take; // continue
        },
        onException: (fileSystem, entity, stat, exception, stackTrace) async {
          opt.logger.error(exception.toString());
          return VisitResult.take; // continue
        });
  }

  if (opt.isCountOnly) {
    final value = NumberFormat().format(count);
    final units = (count == 1 ? 'entry' : 'entries');
    opt.logger.out('$value $units found');
  }
}

更多关于Flutter文件扩展名处理插件file_ext的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件扩展名处理插件file_ext的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在 Flutter 中,file_ext 是一个用于处理文件扩展名的插件。它可以帮助你轻松地获取文件的扩展名、文件名(不带扩展名)以及检查文件是否具有特定的扩展名。以下是如何使用 file_ext 插件的详细步骤。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 file_ext 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  file_ext: ^1.0.0  # 请使用最新版本

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

2. 导入插件

在你的 Dart 文件中导入 file_ext 插件。

import 'package:file_ext/file_ext.dart';

3. 使用 FileExt

FileExt 类提供了多种方法来处理文件扩展名。

获取文件扩展名

你可以使用 getExtension 方法来获取文件的扩展名。

String filePath = '/path/to/file/example.txt';
String extension = FileExt.getExtension(filePath);
print('File extension: $extension');  // 输出: File extension: .txt

获取文件名(不带扩展名)

你可以使用 getFileNameWithoutExtension 方法来获取文件名,但不包括扩展名。

String filePath = '/path/to/file/example.txt';
String fileNameWithoutExtension = FileExt.getFileNameWithoutExtension(filePath);
print('File name without extension: $fileNameWithoutExtension');  // 输出: File name without extension: example

检查文件是否具有特定扩展名

你可以使用 hasExtension 方法来检查文件是否具有特定的扩展名。

String filePath = '/path/to/file/example.txt';
bool hasTxtExtension = FileExt.hasExtension(filePath, 'txt');
print('Has .txt extension: $hasTxtExtension');  // 输出: Has .txt extension: true

4. 处理多个扩展名

FileExt 还支持处理多个扩展名的情况。

String filePath = '/path/to/file/example.tar.gz';
String extension = FileExt.getExtension(filePath);
print('File extension: $extension');  // 输出: File extension: .gz

String allExtensions = FileExt.getAllExtensions(filePath);
print('All extensions: $allExtensions');  // 输出: All extensions: .tar.gz

5. 其他方法

FileExt 还提供了其他一些有用的方法,例如 getFileName 获取完整的文件名,getDirectoryName 获取文件所在的目录等。

String filePath = '/path/to/file/example.txt';
String fileName = FileExt.getFileName(filePath);
print('File name: $fileName');  // 输出: File name: example.txt

String directoryName = FileExt.getDirectoryName(filePath);
print('Directory name: $directoryName');  // 输出: Directory name: /path/to/file
回到顶部