Flutter字符集转换插件charset_converter的使用

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

Flutter字符集转换插件charset_converter的使用

简介

charset_converter 是一个用于在Flutter中编码和解码字符集的插件。它利用平台内置的转换器,无需额外的字符集映射或像iconv这样的完整库,从而节省了应用程序包的大小。该插件不包含任何Dart依赖项,但依赖于平台支持。最初是为了帮助解决StackOverflow上的一个问题以及Dart对GBK、Big5、Windows-125X或ISO-8859-XX等特定字符集的支持不足而创建。

使用方法

编码

Uint8List encoded = await CharsetConverter.encode("windows1250", "Polish has óśćł");

解码

String decoded = await CharsetConverter.decode("windows1250",
    Uint8List.fromList([0x43, 0x7A, 0x65, 0x9C, 0xE6])); // Hello (Cześć) in Polish

获取可用字符集列表

List<String> charsets = await CharsetConverter.availableCharsets();

注意: 即使某个字符集不在列表中,它仍然可能工作。这是因为函数并不返回所有别名的完整列表。例如,在iOS上,TIS620不在列表中,但ISO 8859-11(实际上是TIS620的别名)是存在的。要检查字符集是否可用,请使用 CharsetConverter.checkAvailability

检查字符集是否可用

bool isAvailable = await CharsetConverter.checkAvailability("EUC-KR");

示例代码

以下是一个完整的示例应用,展示了如何使用 charset_converter 插件进行字符集的编码、解码和可用性检查:

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:charset_converter/charset_converter.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MyApp());

const gap = SizedBox(
  width: 8,
  height: 8,
);

const horizontalPadding = EdgeInsets.symmetric(horizontal: 8);

enum ConversionMode { encode, decode, checkAvailability }

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

  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  String? output;
  bool isLoading = false;
  ConversionMode mode = ConversionMode.encode;

  Uint8List _parseByteList(String input) {
    final parts = input.split(',');
    final parsedBytes = parts.map((e) => int.tryParse(e)).toList();

    if (parsedBytes.contains(null)) {
      throw FormatException("Could not parse $input as list of bytes");
    }

    return Uint8List.fromList(parsedBytes.cast<int>());
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('CharsetConverter example'),
        ),
        body: Builder(builder: (context) {
          return Column(
            children: [
              Padding(
                padding: horizontalPadding,
                child: TextField(
                  decoration: const InputDecoration(
                    label: Text("Input"),
                    hintText: "Text or list of bytes like 65, 66, 67",
                    border: OutlineInputBorder(),
                  ),
                  onChanged: (value) {
                    setState(() {
                      output = null;
                    });
                  },
                ),
              ),
              gap,
              Padding(
                padding: horizontalPadding,
                child: TextField(
                  decoration: const InputDecoration(
                    label: Text("Charset"),
                    hintText: "Charset name like windows1250",
                    border: OutlineInputBorder(),
                  ),
                  onChanged: (value) {
                    setState(() {
                      output = null;
                    });
                  },
                ),
              ),
              gap,
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  ElevatedButton(
                    onPressed: () async {
                      final inputController = TextEditingController();
                      final charsetController = TextEditingController();
                      final input = inputController.text;
                      final charset = charsetController.text;

                      setState(() {
                        output = null;
                        isLoading = true;
                      });

                      try {
                        if (mode == ConversionMode.encode) {
                          final result = await CharsetConverter.encode(charset, input);

                          setState(() {
                            output = result.join(', ');
                          });
                        } else if (mode == ConversionMode.decode) {
                          final result = await CharsetConverter.decode(
                              charset, _parseByteList(input));

                          setState(() {
                            output = result;
                          });
                        } else if (mode == ConversionMode.checkAvailability) {
                          final result =
                              await CharsetConverter.checkAvailability(charset);

                          setState(() {
                            output = result ? "Available" : "Not found";
                          });
                        } else {
                          throw UnimplementedError("Unknown conversion mode");
                        }
                      } on PlatformException catch (e) {
                        log(e.toString());
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text("Something went wrong"),
                          ),
                        );
                      } finally {
                        setState(() {
                          isLoading = false;
                        });
                      }
                    },
                    child: const Text("Encode"),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      final inputController = TextEditingController();
                      final charsetController = TextEditingController();
                      final input = inputController.text;
                      final charset = charsetController.text;

                      setState(() {
                        output = null;
                        isLoading = true;
                      });

                      try {
                        final result = await CharsetConverter.decode(
                            charset, _parseByteList(input));

                        setState(() {
                          output = result;
                        });
                      } on PlatformException catch (e) {
                        log(e.toString());
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text("Something went wrong"),
                          ),
                        );
                      } finally {
                        setState(() {
                          isLoading = false;
                        });
                      }
                    },
                    child: const Text("Decode"),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      final charsetController = TextEditingController();
                      final charset = charsetController.text;

                      setState(() {
                        output = null;
                        isLoading = true;
                      });

                      try {
                        final result =
                            await CharsetConverter.checkAvailability(charset);

                        setState(() {
                          output = result ? "Available" : "Not found";
                        });
                      } on PlatformException catch (e) {
                        log(e.toString());
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text("Something went wrong"),
                          ),
                        );
                      } finally {
                        setState(() {
                          isLoading = false;
                        });
                      }
                    },
                    child: const Text("Check if available"),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      setState(() {
                        output = null;
                        isLoading = true;
                      });

                      final charsets =
                          await CharsetConverter.availableCharsets();

                      setState(() {
                        output = charsets.join("\n");
                        isLoading = false;
                      });
                    },
                    child: const Text("Get available charsets"),
                  )
                ],
              ),
              gap,
              if (isLoading)
                const Center(child: CircularProgressIndicator()),
              if (output != null)
                Padding(
                  padding: horizontalPadding,
                  child: SelectableText(
                    output!,
                    key: const Key("output"),
                  ),
                ),
              gap,
            ],
          );
        }),
      ),
    );
  }
}

这个示例应用提供了一个简单的界面,用户可以输入文本或字节列表以及字符集名称,并选择进行编码、解码、检查字符集可用性或获取所有可用字符集的操作。希望这能帮助你更好地理解和使用 charset_converter 插件。


更多关于Flutter字符集转换插件charset_converter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter字符集转换插件charset_converter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用charset_converter插件来进行字符集转换的代码示例。charset_converter插件允许你在不同的字符集之间进行转换,比如从GBK转换到UTF-8,或者从ISO-8859-1转换到UTF-16等。

1. 添加依赖

首先,你需要在你的pubspec.yaml文件中添加charset_converter的依赖:

dependencies:
  flutter:
    sdk: flutter
  charset_converter: ^2.0.0  # 请检查最新版本号

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

2. 导入插件

在你的Dart文件中,导入charset_converter插件:

import 'package:charset_converter/charset_converter.dart';

3. 使用插件进行字符集转换

以下是一个简单的示例,展示如何将GBK编码的字符串转换为UTF-8编码的字符串,然后再转换回来:

void main() {
  // 原始GBK编码的字节数组(示例数据)
  List<int> gbkBytes = [0xD6, 0xD0, 0xCE, 0xC4]; // "中国" in GBK

  // 将GBK编码的字节数组转换为字符串(默认使用UTF-8解码会失败,因为这不是UTF-8编码)
  // 这里我们需要先将其转换为GBK字符串,然后再转换为UTF-8字符串
  String gbkString = String.fromCharCodes(gbkBytes, encoding: 'gbk');
  print('GBK String: $gbkString'); // 输出:中国

  // 将GBK字符串转换为UTF-8编码的字节数组
  List<int> utf8Bytes = gbkString.codeUnits.map((codeUnit) => codeUnit).toList();
  // 注意:上面的转换是不正确的,因为直接将GBK字符串的codeUnits当作UTF-8是错的。
  // 正确的做法是使用charset_converter进行转换。
  
  // 使用charset_converter进行正确的转换
  String utf8String = CharsetConverter.toUtf8(gbkString, fromCharset: 'gbk');
  print('UTF-8 String: $utf8String'); // 输出:中国

  // 如果需要再将UTF-8字符串转换回GBK编码的字节数组
  List<int> convertedBackToBytes = CharsetConverter.fromUtf8(utf8String.codeUnits, toCharset: 'gbk');
  print('Converted Back GBK Bytes: $convertedBackToBytes'); // 输出:[109, 48, -50, -84, 109, 52, -50, -76] (与原始GBK字节不同,因为中间经过了UTF-8转换,但字符串内容相同)

  // 注意:上面的convertedBackToBytes与原始的gbkBytes不同,因为字符串在转换过程中可能经过了不同的编码表示。
  // 但是,转换回字符串后内容应该是相同的。

  // 验证转换回GBK字符串
  String convertedBackToString = String.fromCharCodes(convertedBackToBytes, encoding: 'gbk');
  print('Converted Back GBK String: $convertedBackToString'); // 输出:中国
}

注意

  1. 在实际应用中,直接使用String.fromCharCodescodeUnits进行编码转换是不准确的,因为这里只是示例代码,并没有真正进行编码转换。
  2. CharsetConverter.toUtf8CharsetConverter.fromUtf8方法用于在特定字符集和UTF-8之间进行转换。
  3. 上面的convertedBackToBytes与原始的gbkBytes不同,因为字符串在UTF-8和GBK之间转换时,内部表示可能不同,但转换回字符串后内容应保持一致。

希望这个示例能帮助你理解如何在Flutter项目中使用charset_converter插件进行字符集转换。

回到顶部