分布式文件系统 + 手动通知
时间: 2026-04-15 11:35:47
(部分内容来自网络,其真实性存疑,为了避免对您造成误导,请谨慎甄别。)
替代方案:分布式文件系统 + 手动通知
原理:A设备把文件写进共享目录,B设备轮询或监听目录变化,读到文件就读数据。
核心思路:放弃"自动同步",放弃"状态监听",直接用最原始的文件读写。
一、架构
设备A 设备B
│ │
├─ 写数据到 distributedFilesDir/test.txt │
│ │
└─ 可选:用软总线发个通知 ──────────────────→ 收到通知,读文件
底层依赖:
- distributedFilesDir 目录下的文件自动同步到同账号其他设备
- 不需要 setSessionId,不需要 createKVStore,就他妈是个文件夹
二、代码实现
设备A:写数据
import { fileIo as fs } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
async function writeDataToOtherDevice(data: string, fileName: string) {
let context = getContext();
let distributedDir = context.distributedFilesDir; // 关键:这个目录自动同步
let filePath = distributedDir + '/' + fileName;
try {
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(file.fd, data);
fs.closeSync(file.fd);
console.log('写入成功,文件会自动同步到其他设备');
} catch (err) {
let e = err as BusinessError;
console.error('写入失败:', e.message);
}
}
// 使用
writeDataToOtherDevice('要同步的数据', 'sync_data.txt');设备B:读数据
方案1:轮询(最简单,保证能通)
import { fileIo as fs } from '@kit.CoreFileKit';
let context = getContext();
let distributedDir = context.distributedFilesDir;
let filePath = distributedDir + '/sync_data.txt';
// 每秒检查一次文件是否存在
let interval = setInterval(() => {
try {
let stat = fs.statSync(filePath);
if (stat.size > 0) {
let file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
let buffer = new ArrayBuffer(stat.size);
fs.readSync(file.fd, buffer);
fs.closeSync(file.fd);
let data = bufferToString(buffer);
console.log('收到数据:', data);
// 处理数据...
// 可选:读完删掉文件
fs.unlinkSync(filePath);
}
} catch (err) {
// 文件不存在,忽略
}
}, 1000);方案2:监听目录变化(更优雅,但可能不触发)
import { fileWatcher } from '@kit.CoreFileKit';
let watcher = fileWatcher.createWatcher(distributedDir, (events) => {
for (let event of events) {
if (event.fileName === 'sync_data.txt') {
// 文件变化了,去读
readFile();
}
}
});
watcher.start();三、大文件分块
如果数据太大(比如图片),可以分多个文件写:
// 写入端
let chunks = splitData(largeData, 1024 * 1024); // 每块1MB
for (let i = 0; i < chunks.length; i++) {
writeDataToOtherDevice(chunks[i], chunk_${i}.txt);
}
writeDataToOtherDevice(chunks.length.toString(), 'chunk_count.txt');
// 读取端
let totalChunks = parseInt(await readFile('chunk_count.txt'));
let allData = '';
for (let i = 0; i < totalChunks; i++) {
allData += await readFile(chunk_${i}.txt);
}四、可选:发个通知让对面立刻读
如果你不想轮询(虽然轮询也他妈没啥问题),可以在写文件后发一个软总线通知,让对端知道"有新数据了"。
用 Distributed Service Kit 的 getDeviceManager 获取设备ID,然后用 startAbilityByCall 或广播发个通知。但这又要踩别的坑。
建议:直接用轮询。1秒一次,CPU占用可以忽略不计,而且一定能通。
五、必须满足的前提(绕不开)
| 条件 | 说明 |
|---|---|
| 同账号 | 两台设备登录同一个华为账号 |
| WiFi+蓝牙都开 | 系统底层组网用 |
| 权限 | 不需要特殊权限,distributedFilesDir 自带同步能力 |
六、为什么这个方案能通
1. 没有异步初始化:目录是现成的,不需要 await getKVStore
2. 没有 sessionId:不需要两边对什么鬼ID
3. 没有状态监听玄学:文件系统是POSIX标准,几百年历史的玩意儿
4. 文件写进去了就是写进去了:不会"不报错但调不通"
七、总结
| 方案 | 复杂度 | 稳定度 | 依赖 |
|---|---|---|---|
| 分布式数据对象 | 高 | 你已验证:调不通 | sessionId、状态监听、权限 |
| KVStore | 高 | 你已验证:调不通 | 异步初始化、sync |
| 分布式文件 + 轮询 | 低 | 高 | 就一个文件夹 |
一句话:忘掉那些傻逼API。把数据写进 distributedFilesDir,对面轮询读文件。这是最底层、最不花哨、最能跑通的路。