HarmonyOS 鸿蒙Next怎么打开读取下载内容路径下的文件

发布于 1周前 作者 nodeper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next怎么打开读取下载内容路径下的文件
<markdown _ngcontent-nie-c237="" class="markdownPreContainer">

let filePath = pathDir + “/test.txt”;
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE);
let buf = new ArrayBuffer(4096);
let num = fs.readSync(file.fd, buf);
fs.closeSync(file);
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

引用官网的示例,我把filepath改为/storage/emulated/0/Download/test.txt, 跑到第二行就会崩溃,Error message:No such file or directory.

所以想求教应该怎么读取到路径为:文件->下载内容 中的文件?(该文件是从windows桌面拖拽了一个text.txt文件到模拟器里的)

</markdown>
15 回复

要读取sdcard/download路径下的文件可能需要降到api 8。
通过api 8 的媒体库的方法可以读取到相关路径,然后获取目标路径的fd;

然后用fd去 fileio 模块调用相关路径解析文件,但是有个问题我没有办法解决,就是下面例子里的open方法属于媒体库下的方法,好像只能打开媒体资源,例如png、jpg等文件。我是直接将把png文件当成文本文件读取的,暂时没发现问题;

let media = mediaLibrary.getMediaLibrary();
// 创建文件获取选项,此处参数为获取image类型的文件资源
    let imagesFetchOp = {
      // selections: fileKeyObj.MEDIA_TYPE + '= ?',
      selections: mediaLibrary.FileKey.ALBUM_NAME + '= ?',
      selectionArgs: ["Download"],
    };
<span class="hljs-comment"><span class="hljs-comment">// 获取文件资源,使用callback方式返回异步结果</span></span>
media.getFileAssets(imagesFetchOp, async (error, fetchFileResult) =&gt; {
  <span class="hljs-comment"><span class="hljs-comment">// 获取文件检索结果集中的总数</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> count = fetchFileResult.getCount();
  console.info(<span class="hljs-string"><span class="hljs-string">'日志:检索内容数量:'</span></span> + count);
  <span class="hljs-comment"><span class="hljs-comment">// 判断结果集中的数量是否小于0,小于0时表示接口调用失败</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (count &lt;= <span class="hljs-number"><span class="hljs-number">0</span></span>) {
    console.error(<span class="hljs-string"><span class="hljs-string">'日志:检索异常, count: '</span></span> + count);
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>;
  }
  fetchFileResult.getAllObject(async (err, fileAssetList) =&gt; {
    <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (err) {
      console.error(<span class="hljs-string"><span class="hljs-string">'日志:Failed '</span></span>);
      <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>;
    }
    <span class="hljs-keyword"><span class="hljs-keyword">for</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> i = <span class="hljs-number"><span class="hljs-number">0</span></span>; i &lt; count; i++) {
      <span class="hljs-comment"><span class="hljs-comment">// console.log('日志: fileAsset.displayName : ' + fileAssetList[i].displayName);</span></span>
      <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> fileAsset = fileAssetList[i];
      console.info(<span class="hljs-string"><span class="hljs-string">'日志:[fileAsset.displayName] '</span></span> + i + <span class="hljs-string"><span class="hljs-string">': '</span></span> + fileAsset.displayName);
      <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (fileAsset.displayName === <span class="hljs-string"><span class="hljs-string">"userList.bmp"</span></span>) {
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> fd = await fileAsset.open(<span class="hljs-string"><span class="hljs-string">'r'</span></span>)
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> stream = fileio.fdopenStreamSync(fd, <span class="hljs-string"><span class="hljs-string">'r'</span></span>)
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> readOut = await stream.read(<span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">ArrayBuffer</span></span>(<span class="hljs-number"><span class="hljs-number">10000000</span></span>));
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> textDecoder = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> util.TextDecoder(<span class="hljs-string"><span class="hljs-string">"utf-8"</span></span>, { ignoreBOM: <span class="hljs-literal"><span class="hljs-literal">true</span></span> });
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> buffer = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>(readOut.buffer)
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> readString = textDecoder.decode(buffer, { stream: <span class="hljs-literal"><span class="hljs-literal">false</span></span> });
        console.info(<span class="hljs-string"><span class="hljs-string">"日志:[userList]"</span></span> + readString.replace(<span class="hljs-regexp"><span class="hljs-regexp">/[\n\r]+/g</span></span>, <span class="hljs-string"><span class="hljs-string">""</span></span>))
      }
    }
  })
});</code><button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button></pre></div></div>

可行!我转成txt格式后,确实能读到了。还想请问下,这种方法通过检索文件实现的,MediaLibrary支持FILE,AUDIO,VIDEO,IMAGE四种类型,但是没有文件夹类型的,这种方法可以实现检索文件夹吗,现在就是想将一个公共目录下的文件夹复制到沙箱目录中

在我的尝试中,媒体库api好像只能读第一层,就比如可以遍历Dowaload文件夹下的内容,但是我如果建一个Download/Bill这样的文件夹的话,只能读到Bill的这个文件夹,里面的内容没有找到相应的api打开,因为没有“通过fd打开文件夹或者说通过fd读取文件夹下内容”这种功能的api。 所以你的这个需求“将一个公共目录下的文件夹复制到沙箱目录中”,可能得把你的文件夹建在外层(和Download同级),然后用相同的操作遍历下面的文件,再依次将内容读出来,往沙盒目录下写。 因为没有翻到相关的参考文档,我不确定通过修改selectionArgs配置能不能直接找到二级目录,只能走歪路子了。。。

如果要像我说的直接建立一级目录的话,修改selectionArgs配置项,把你的文件名替换“Download”就行

试试 
fs.OpenMode.READ_ONLY

再看看有没有添加权限

"name": "ohos.permission.WRITE_MEDIA"

请问有没有添加这个权限应该在哪里看

entry\src\main\module.json5 ,或者你全局搜requestPermissions,如果没搜到就去文档里搜看看这在哪里配置

加了,不过好像还是没解决

如果你是指sd卡的话,得看你是什么系统。就我现在来看HarmonyOS只能读取沙箱路径里的,因为读取分卷的概念只存在OpenHarmony接口,且需要系统级权限。

你如果想推文件,可能用hdc 指令会更好,但我不清楚OS有没有这个能力

感谢回复,我目前就是用的OpenHarmony API9接口,现在的需求就是要打开读取sdcard/download路径下的xml文件,然后解析。OpenHarmony中有相关的支持接口吗,我好像没有看到。给的xml示例也是一小段的,没有读文件解析的相关内容。

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

哦,记错了,我上次是看到的是挂载,不涉及到文件读取。不过我看到了这个接口,你可以试一下 https://docs.openharmony.cn/pages/v4.0/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md

你好,我也在查楼主类似的需求解决方案,您链接的这个api貌似用不了啊,api介绍上提到了如下内容: 本模块首批接口从API version 9开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 本模块接口为系统接口,三方应用不支持调用,当前只支持FilePicker、文件管理器调用。

请问问题解决了吗 @ohos.file.environment (目录环境能力)-ArkTS API-Core File Kit(文件基础服务)-应用框架 - 华为HarmonyOS开发者 (huawei.com) 这个方法可以找到公共目录下的问文件 但我的需求是获取公共目录下的说有文件 请问当时解决了吗 有没有思路可以借鉴一下

在HarmonyOS鸿蒙Next中打开并读取下载内容路径下的文件,你可以使用系统的文件访问API。首先,确保你有足够的权限去访问该路径。然后,使用fs.open()fs.openSync()方法打开文件,并指定合适的模式(如只读)。接着,使用fs.read()fs.readSync()读取文件内容到缓冲区中。最后,处理读取到的数据,并在完成后关闭文件。如果路径或文件不存在,可能需要检查路径是否正确或文件是否已被删除。如果问题依旧没法解决请加我微信,我的微信是itying888。

回到顶部