HarmonyOS鸿蒙Next中将用户输入的信息保存为txt格式,然后保存在手机文件中,打开发现没有数据是怎么回事?

HarmonyOS鸿蒙Next中将用户输入的信息保存为txt格式,然后保存在手机文件中,打开发现没有数据是怎么回事? 上面第二个是打开按钮,第三个是保存按钮,点第三个按钮,就把下面文本框的内容,保存到一个文件中,文件名可以输入,就像word,note一样。点第二个键,可以选择打开以前保存的文件,并且把文件内容,放到下面的文本框里。

cke_3281.png

目录要是上次选定的目录才更方便。保存的文件是空的,里面没有保存东西。全部0kb


更多关于HarmonyOS鸿蒙Next中将用户输入的信息保存为txt格式,然后保存在手机文件中,打开发现没有数据是怎么回事?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

开发者你好,将文档保存到用户手机上需要先把文件保存到沙箱路径再转到手机。否则保存的文件是无任何字节数据

参考示例:

import { BusinessError, request } from '@kit.BasicServicesKit';
import fs, { ReadOptions } from '@ohos.file.fs';
import { common } from '@kit.AbilityKit';
import picker from '@ohos.file.picker';
import { buffer } from '@kit.ArkTS';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct DocumentSave {
  @State message: string = '请输入内容并保存';
  @State userInput: string = ''; // 存储用户输入的文本
  build() {
    Column({ space: 20}) {
      // 标题
      Text(this.message)
        .fontSize(24)
        .fontWeight(FontWeight.Medium)
        .fontColor(Color.Black)
        .margin({ bottom: 30 })
      // 用户输入框
      TextInput({ placeholder: '请输入要保存的文本内容' ,text:$$this.userInput})
        .type(InputType.Normal)
        .placeholderColor(Color.Gray)
        .fontSize(18)
        .fontWeight(FontWeight.Normal)
        .height(50)
        .width('80%')
        .margin({ bottom: 20 })
      // 保存按钮
      Button('保存到本地')
        .width('80%')
        .height(50)
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .backgroundColor('#007DFF')
        .fontColor(Color.White)
        .onClick(() => {
          this.saveTextToFile();
          this.userInput =''
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Start)
  }
  /**
   * 保存文本到本地(沙箱→公共目录)
   */
  private async saveTextToFile() {
    if (!this.userInput.trim()) {
      promptAction.showToast({ message: '请输入文本内容' });
      return;
    }
    const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
    const sandboxFilePath = context.filesDir + '/temp.txt'; // 沙箱临时文件路径
    try {
      // 1. 写入沙箱临时文件
      await this.writeToSandbox(sandboxFilePath);
      // 2. 复制到公共目录(Download文件夹)
      await this.copyToPublic(sandboxFilePath);
    } catch (error) {
      console.error('保存文件失败:', error);
      promptAction.showToast({ message: '保存失败:' + (error as BusinessError).message });
    }
  }
  /**
   * 写入内容到沙箱文件
   * @param filePath 沙箱文件路径
   * @param content 要写入的内容
   */
  private async writeToSandbox(filePath: string) {
    // 文件不存在时创建并打开文件,文件存在时打开文件
    let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    // 写入一段内容至文件
    let writeLen = fs.writeSync(file.fd, this.userInput);
    console.info("The length of str is: " + writeLen);
    //计算文件大小
    const fileSize = fs.statSync(file.fd).size;
    // 创建一个ArrayBuffer对象,用于存储从文件中读取的数据
    let arrayBuffer = new ArrayBuffer(fileSize);
    // 设置读取的偏移量和长度
    let readOptions: ReadOptions = {
      offset: 0,
      length: arrayBuffer.byteLength
    };
    // 读取文件内容到ArrayBuffer对象中,并返回实际读取的字节数
    let readLen = fs.readSync(file.fd, arrayBuffer, readOptions);
    // 将ArrayBuffer对象转换为Buffer对象,并转换为字符串输出
    let buf = buffer.from(arrayBuffer, 0, readLen);
    console.info("the content of file: " + buf.toString());
    // 关闭文件
    fs.closeSync(file);
  }
  /**
   * 复制沙箱文件到公共目录
   * @param sourcePath 源文件路径(沙箱)
   */
  private async copyToPublic(sourcePath: string) {
    const documentSaveOptions = new picker.DocumentSaveOptions(); // 创建文件管理器保存选项实例
    documentSaveOptions.newFileNames = ["icon.txt"]; // 保存文件名(可选)
    const documentViewPicker = new picker.DocumentViewPicker;
    documentViewPicker.save(documentSaveOptions)
      .then(async (documentSaveResult) => {
        // 获取到到图片或者视频文件的URI后进行文件读取等操作
        let uri = documentSaveResult[0];
        console.info('pub uri:' + uri)
        // 沙箱路径文件
        let sanFile = fs.openSync(sourcePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
        let pubFile = fs.openSync(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
        promptAction.showToast({ message: '文件保存成功:' + uri });
        // 将文件从沙箱路拷贝到公共路径
        fs.copyFileSync(sanFile.fd, pubFile.fd)
      })
      .catch((err:Error) => {
        console.error(`Invoke documentPicker.select failed, message is ${err.message}`); })
  }
}

更多关于HarmonyOS鸿蒙Next中将用户输入的信息保存为txt格式,然后保存在手机文件中,打开发现没有数据是怎么回事?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,用户输入信息保存为txt文件后无数据,可能原因包括:文件写入后未正确关闭流,导致数据未刷新到存储;文件路径权限不足,应用无法在目标目录写入;使用了异步操作但未等待完成,数据尚未持久化;文件被其他进程锁定或占用。检查代码中是否调用flush()和close()方法,确认使用正确的沙箱路径,并验证写入操作的同步执行。

在HarmonyOS Next中保存文件后内容为空,通常由以下几个原因导致:

  1. 文件写入未正确执行

    • 检查是否调用了fsync()close()方法确保数据从缓冲区写入存储
    • 示例代码片段:
      let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      fs.writeSync(file.fd, content);
      fs.fsyncSync(file.fd); // 确保数据持久化
      fs.closeSync(file);
      
  2. 路径权限问题

    • 确认使用的ohos.file.fs接口具有对应目录的读写权限
    • module.json5中配置存储权限:
      "requestPermissions": [
        {
          "name": "ohos.permission.READ_MEDIA",
          "reason": "$string:reason"
        }
      ]
      
  3. 异步操作未完成

    • 若使用Promise异步写入,需确保await执行完成:
      await fs.promises.writeFile(path, content);
      
  4. 文件路径异常

    • 通过fs.accessSync()验证路径有效性
    • 使用context.filesDir获取应用安全目录路径

建议重点检查数据持久化步骤和权限配置,这两个是导致空文件的常见原因。

回到顶部