Files
youle_app_ohos/platform/src/main/ets/fs/FileSystem.ets
T
lanterngamescnandClaude Opus 4.8 5cbe5d4dd0 M3(T-M3-13): 分享面板对齐原工程——微信SDK + QQ/抖音系统分享
对齐 Android SharePanelHelper 流程:H5 friendsSharetypeUrlToptitleDescript →
原生弹自定义面板(微信/QQ/抖音) → 按所选平台分享。

- common ShareEvents:SHOW_PANEL + SharePanelRequest/Result;ShareProvider 经一次性
  resultEvent 与 entry 容器一对一解耦(双槽实例隔离,避免广播串扰)
- ShareProvider 重构:微信走 SDK(type2 Canvas截图→WXImageObject / 其他→WXWebpageObject;
  scene 好友/朋友圈;回传 sharesuccess);QQ/抖音走 @kit.ShareKit 系统分享(文本/图片/链接/视频,
  不集成对应 SDK、不回传);截图失败统一降级
- 截图:CapabilityContext.captureCanvas(WebSlot 用 controller.runJavaScript 取 canvas
  toDataURL,非激活/出错返回空);FileSystem.writeBytes 落盘;fileUri 给 WXImageObject/系统分享
- entry SharePanel 组件 + BridgeGameContainer 顶层叠加;重复面板/销毁均取消回投防 once 悬挂

真机验证项:微信开放平台注册后的真分享、系统分享面板拉起、canvas 截图

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:00:03 +08:00

116 lines
4.0 KiB
Plaintext

/**
* 文件系统工具(框架 §8.3 / 附录 A.4)。封装 @kit.CoreFileKit fileIo + resourceManager。
*
* 供 ResourceManager / AppDataInjector 使用:建目录、读写文本、递归删除、列目录、
* 把随包内置 rawfile(内置预置包 zip)拷贝到沙箱。纯原生内部 IO,H5 无感知。
*/
import { fileIo as fs } from '@kit.CoreFileKit';
import { resourceManager } from '@kit.LocalizationKit';
import { Logger } from 'common';
export class FileSystem {
private static readonly log: Logger = Logger.tag('FileSystem');
/** 路径是否存在。 */
static exists(path: string): boolean {
try {
return fs.accessSync(path);
} catch (e) {
const err = e as Error;
FileSystem.log.w(`accessSync(${path}) failed: ${err.message}`);
return false;
}
}
/** 递归创建目录(已存在则忽略)。 */
static ensureDir(path: string): void {
if (FileSystem.exists(path)) {
return;
}
fs.mkdirSync(path, true);
}
/** 递归删除文件或目录(不存在/竞态则忽略,绝不抛错——对齐注释承诺)。 */
static rmrf(path: string): void {
if (!FileSystem.exists(path)) {
return;
}
try {
const stat: fs.Stat = fs.statSync(path);
if (stat.isDirectory()) {
fs.rmdirSync(path);
} else {
fs.unlinkSync(path);
}
} catch (e) {
const err = e as Error;
FileSystem.log.w(`rmrf(${path}) ignored: ${err.message}`);
}
}
/** 重命名/移动(同文件系统)。用于资源原子换入。 */
static rename(oldPath: string, newPath: string): void {
fs.renameSync(oldPath, newPath);
}
/** 写文本(覆盖;自动建父目录)。 */
static writeText(path: string, content: string): void {
FileSystem.ensureDir(FileSystem.dirOf(path));
const file: fs.File = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE | fs.OpenMode.TRUNC);
try {
fs.writeSync(file.fd, content);
} finally {
fs.closeSync(file);
}
}
/** 写二进制(覆盖;自动建父目录)。用于截图分享落盘等。 */
static writeBytes(path: string, bytes: Uint8Array): void {
FileSystem.ensureDir(FileSystem.dirOf(path));
const file: fs.File = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE | fs.OpenMode.TRUNC);
try {
// 按实际视图(byteOffset/byteLength)写入,避免底层 buffer 为大池子视图时写多余字节
const view: ArrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;
fs.writeSync(file.fd, view);
} finally {
fs.closeSync(file);
}
}
/** 读文本(不存在返回空串)。 */
static readText(path: string): string {
if (!FileSystem.exists(path)) {
return '';
}
return fs.readTextSync(path);
}
/** 列目录条目名(不存在返回空数组)。 */
static listDir(path: string): string[] {
if (!FileSystem.exists(path)) {
return [];
}
return fs.listFileSync(path);
}
/** 把随包内置 rawfile 拷贝到沙箱目标路径(用于内置预置包 zip)。 */
static copyRawFileTo(resMgr: resourceManager.ResourceManager, rawFilePath: string, destPath: string): void {
const bytes: Uint8Array = resMgr.getRawFileContentSync(rawFilePath);
FileSystem.ensureDir(FileSystem.dirOf(destPath));
const file: fs.File = fs.openSync(destPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE | fs.OpenMode.TRUNC);
try {
// 按 Uint8Array 的实际视图(byteOffset/byteLength)写入,避免底层 buffer 为大池子视图时写入多余字节致 zip 损坏
const view: ArrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;
fs.writeSync(file.fd, view);
} finally {
fs.closeSync(file);
}
}
/** 取父目录路径(无分隔符则返回原串)。 */
static dirOf(path: string): string {
const idx: number = path.lastIndexOf('/');
return idx > 0 ? path.substring(0, idx) : path;
}
}