HarmonyOS 鸿蒙Next 调起文件管理器获取txt文件,并且根据正确文件编码读取文件内的文本信息,避免读取的文本是乱码

发布于 1周前 作者 vueper 最后一次编辑是 5天前 来自 鸿蒙OS

研究了两天,期望能帮助其他初学者。这里引用了一个第三方库来获取文件实际的编码(也是在别人的贴子里学习的)。

在终端命令行拉取插件:

ohpm install @ohos/juniversalchardet

逻辑封装代码:

../constants/fileManagement.ets
import { common } from '@kit.AbilityKit';
import  { picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileUri } from '@kit.CoreFileKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { util } from '@kit.ArkTS';
// 获取第三方插件
import {UniversalDetector} from '@ohos/juniversalchardet'
const context = getContext(this)
// 调起文件管理器
export function showFileManagement(context: common.Context, callback:Function) { // 需确保 context 由 UIAbilityContext 转换而来
  try {
    let documentSelectOptions = new picker.DocumentSelectOptions();
    documentSelectOptions.maxSelectNumber = 1;
    documentSelectOptions.fileSuffixFilters = ['.txt'];
    let documentPicker = new picker.DocumentViewPicker(context);
    documentPicker.select(documentSelectOptions, (err: BusinessError, documentSelectResult: Array<string>) => {
      if (err) {
        console.error('DocumentViewPicker.select failed with err: ' + JSON.stringify(err));
        return;
      }
      // 获取URL后的回调函数
      callback(documentSelectResult[0] as string)
    });
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    console.error('DocumentViewPicker failed with err: ' + JSON.stringify(err));
  }
}

export interface fileData {
  path: string;
  size: number;
  name: string;
  txt: string;
}
// 获取数据 size = 0 时取全量数据
export function fileDataManagement(size:number,callback:Function){
  showFileManagement(context as common.Context, (url: string) => {
    // 转换为可用路径
    const path: string = new fileUri.FileUri(url).path;
    const arr = path.split('/')
    const name: string = arr[arr.length-1].split('.')[0]
    // 获取文件编码
    UniversalDetector.detectCharset(path)
      .then((encoding: string) => {
        // encoding 获取文件编码
        // console.log(encoding)
        // 读取文件
        let stream = fs.createStreamSync(path, "r+");

        // console.log(JSON.stringify(stat))
        let buffer = new ArrayBuffer(size);
        if(size === 0){
          let stat = fs.statSync(path); // 获取文件大小
          buffer = new ArrayBuffer(stat.size)
        }

        let readOut = stream.readSync(buffer);
        // 根据对应encoding编码转换文本信息
        let textDecoder = util.TextDecoder.create(encoding, { ignoreBOM: true });
        let readString = textDecoder.decodeToString(new Uint8Array(buffer), { stream: false });
        // 打印输出
        // readString
        const obj:fileData = {
          path: path,
          size: readString.length,
          name: name,
          txt: readString
        }
        callback(obj as fileData)
      })
      .catch((err: string) => {
        // 异常信息
      });
  })
}

页面引入使用:

import { fileDataManagement, fileData } from '../constants/fileManagement';
export interface listData {
  id:string;
  path: string;
  size: number;
  name: string;
  txt: string;
}

@Entry
@Component
struct Index {
  @State list: listData[] = [];
  build() {
    List(){
      ListItem() {
        Row() {
          // 选择文件
          Button('选择文件', { type: ButtonType.Normal, stateEffect: false })
            .margin(10)
            .borderRadius(8)
            .backgroundColor(0x317aff)
            .width(90)
            .onClick(() => {
              fileDataManagement(0,(obj:fileData)=>{
                this.list.unshift({
                  id: new Date().getTime().toString(36) + Math.random().toString().slice(2, 10),
                  path: obj.path,
                  size: obj.size,
                  name: obj.name,
                  txt: obj.txt.substring(0, 136).replace(/\r\n+/g, '').replace(/\n+/g, '').replace(/\s+/g, '').substring(0, 36),
                })
              })
            });

        }
      }
      ForEach(this.list, (item: listData) => {
        ListItem() {
          Text("名称:"+item.name+";"+"简介:"+item.txt+";"+"字数:"+item.size+";"+"id:"+item.id)
        }
      }, (item: listData) => item.id)

    }
  }
}

这里只是测试代码,用来验证可行性,同学们可以进一步根据实际需求进行优化和封装。

1 回复

在HarmonyOS鸿蒙Next系统上,调起文件管理器以获取TXT文件,并根据正确文件编码读取文件内容,可以通过以下步骤实现:

  1. 调起文件管理器:利用HarmonyOS提供的文件选择器API,让用户从文件管理器中选择TXT文件。这通常通过Intent或文件选择器组件实现,具体取决于你的应用架构。

  2. 获取文件路径:用户选择文件后,系统会返回文件的URI或路径。确保你的应用有权限访问这个路径。

  3. 读取文件内容:使用Java或Kotlin的文件I/O操作读取文件内容。在读取时,需指定正确的字符编码(如UTF-8、GBK等),以避免乱码。可以使用InputStreamReaderBufferedReader,并指定编码方式,如new InputStreamReader(inputStream, "UTF-8")

  4. 处理文本信息:读取到的文本信息可以进一步处理或显示在应用界面上。

示例代码(简化):

FileInputStream fis = new FileInputStream(filePath);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
    sb.append(line).append("\n");
}
br.close();
String fileContent = sb.toString();

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部