OpenHarmony文件访问接口mod_fileio解析

概述

mod_fileio模块是OpenHarmony文件管理API中的核心模块之一,提供了完整的文件I/O操作功能。该模块基于Node.js N-API构建,为JavaScript应用提供了丰富的文件系统操作接口,包括文件读写、目录操作、流处理、文件监控等功能。

模块架构

目录结构

interfaces/kits/js/src/mod_fileio/
├── class_constants/          # 常量定义
├── class_dir/               # 目录操作类
├── class_dirent/            # 目录条目类
├── class_file/              # 文件操作类
├── class_stat/              # 文件状态类
├── class_stat_v9/           # 文件状态类V9版本
├── class_stream/            # 流操作类
├── class_watcher/           # 文件监控类
├── properties/              # 属性函数实现
├── common_func.cpp          # 公共函数实现
├── common_func.h            # 公共函数声明
├── module.cpp               # 模块导出(标准版本)
└── module_v9.cpp            # 模块导出(V9版本)

模块版本

mod_fileio模块提供了两个版本:

  1. 标准版本 (module.cpp) - 导出为fileio模块
  2. V9版本 (module_v9.cpp) - 导出为fs模块

两个版本在功能上有所差异,V9版本更加精简,主要包含核心的文件操作功能。

核心组件详解

1. 模块导出机制

标准版本 (module.cpp)
static napi_value Export(napi_env env, napi_value exports)
{std::vector<unique_ptr<NExporter>> products;products.emplace_back(make_unique<PropNExporter>(env, exports));products.emplace_back(make_unique<DirentNExporter>(env, exports));products.emplace_back(make_unique<DirNExporter>(env, exports));products.emplace_back(make_unique<StatNExporter>(env, exports));products.emplace_back(make_unique<StreamNExporter>(env, exports));products.emplace_back(make_unique<WatcherNExporter>(env, exports));products.emplace_back(make_unique<Constants>(env, exports));for (auto &&product : products) {if (!product->Export()) {HILOGE("INNER BUG. Failed to export class %{public}s for module fileio", product->GetClassName().c_str());return nullptr;}}return exports;
}
V9版本 (module_v9.cpp)
static napi_value Export(napi_env env, napi_value exports)
{InitOpenMode(env, exports);std::vector<unique_ptr<NExporter>> products;products.emplace_back(make_unique<PropNExporterV9>(env, exports));products.emplace_back(make_unique<FileNExporter>(env, exports));products.emplace_back(make_unique<StatNExporterV9>(env, exports));for (auto &&product : products) {if (!product->Export()) {HILOGE("INNER BUG. Failed to export class %{public}s for module fileio", product->GetClassName().c_str());return nullptr;}}return exports;
}

2. 公共函数模块 (common_func)

文件打开模式常量
constexpr int RDONLY = 00;        // 只读
constexpr int WRONLY = 01;        // 只写
constexpr int RDWR = 02;          // 读写
constexpr int CREATE = 0100;      // 创建
constexpr int TRUNC = 01000;      // 截断
constexpr int APPEND = 02000;     // 追加
constexpr int NONBLOCK = 04000;   // 非阻塞
constexpr int DIRECTORY = 0200000; // 目录
constexpr int NOFOLLOW = 0400000;  // 不跟随符号链接
constexpr int SYNC = 04010000;    // 同步
核心工具函数

CommonFunc类提供了以下关键功能:

  1. ConvertJsFlags - JavaScript标志位转换
  2. GetReadArg - 读取参数解析
  3. GetWriteArg - 写入参数解析
  4. GetCopyPathArg - 复制路径参数解析
  5. InitOpenMode - 初始化打开模式

3. 类组件详解

3.1 目录操作类 (class_dir)

DirNExporter类提供目录操作功能:

class DirNExporter final : public NExporter {
public:static napi_value CloseSync(napi_env env, napi_callback_info info);static napi_value ReadSync(napi_env env, napi_callback_info info);static napi_value ListFileSync(napi_env env, napi_callback_info info);static napi_value Read(napi_env env, napi_callback_info info);static napi_value Close(napi_env env, napi_callback_info info);static napi_value ListFile(napi_env env, napi_callback_info info);
};

主要功能:

  • 同步/异步目录读取
  • 目录关闭
  • 文件列表获取
3.2 文件操作类 (class_file)

FileNExporter类提供基础文件操作:

class FileNExporter final : public NExporter {
public:static napi_value Constructor(napi_env env, napi_callback_info cbinfo);static napi_value GetFD(napi_env env, napi_callback_info cbinfo);
};

主要功能:

  • 文件对象构造
  • 文件描述符获取
3.3 流操作类 (class_stream)

StreamNExporter类提供流式文件操作:

class StreamNExporter final : public NExporter {
public:static napi_value WriteSync(napi_env env, napi_callback_info cbinfo);static napi_value FlushSync(napi_env env, napi_callback_info cbinfo);static napi_value ReadSync(napi_env env, napi_callback_info cbinfo);static napi_value CloseSync(napi_env env, napi_callback_info cbinfo);static napi_value Write(napi_env env, napi_callback_info cbinfo);static napi_value Read(napi_env env, napi_callback_info cbinfo);static napi_value Close(napi_env env, napi_callback_info cbinfo);
};

主要功能:

  • 同步/异步流读写
  • 流刷新
  • 流关闭
3.4 文件状态类 (class_stat)

提供文件状态信息获取功能,包括标准版本和V9版本。

3.5 文件监控类 (class_watcher)

提供文件系统监控功能,可以监听文件变化事件。

4. 属性函数模块 (properties)

properties目录包含了大量的文件操作函数实现,每个函数都有对应的.h和.cpp文件:

核心文件操作函数
函数名功能描述
open打开文件
close关闭文件
read_text读取文本文件
write写入文件
copy_file复制文件
rename重命名文件
unlink删除文件
mkdir创建目录
rmdir删除目录
stat获取文件状态
lstat获取链接状态
chmod修改文件权限
chown修改文件所有者
fsync同步文件数据
fdatasync同步文件数据(不含元数据)
ftruncate截断文件
lseek文件定位
symlink创建符号链接
link创建硬链接
hash计算文件哈希
watcher文件监控
异步操作支持

每个核心函数都提供了同步和异步两个版本:

// 同步版本
static napi_value Sync(napi_env env, napi_callback_info info);// 异步版本  
static napi_value Async(napi_env env, napi_callback_info info);

调用关系图

mod_fileio模块
module.cpp/module_v9.cpp
PropNExporter
DirNExporter
FileNExporter
StreamNExporter
StatNExporter
WatcherNExporter
Constants
properties目录
open/close/read/write等函数
目录操作
文件操作
流操作
状态查询
文件监控
常量定义
common_func
公共工具函数
参数解析
标志位转换
编码处理

接口设计特点

1. 统一的N-API接口

所有类都继承自NExporter基类,提供统一的导出机制:

class NExporter {
public:virtual bool Export() = 0;virtual std::string GetClassName() = 0;
};

2. 同步/异步双重支持

每个核心功能都提供同步和异步两个版本,满足不同场景需求:

  • 同步版本:直接返回结果,适合简单操作
  • 异步版本:通过回调返回结果,适合I/O密集型操作

3. 错误处理机制

使用UniError类进行统一的错误处理:

UniError(EINVAL).ThrowErr(env, "Invalid parameter");

4. 内存管理

使用智能指针管理内存,避免内存泄漏:

std::unique_ptr<char[]> bufferGuard;

核心操作实现详解

1. 文件打开操作实现

同步打开 (Open::Sync)
napi_value Open::Sync(napi_env env, napi_callback_info info)
{NFuncArg funcArg(env, info);if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) {UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");return nullptr;}// 1. 解析路径参数bool succ = false;unique_ptr<char[]> path = nullptr;tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();if (!succ) {UniError(EINVAL).ThrowErr(env, "Invalid path");return nullptr;}// 2. 解析标志位参数unsigned int flags = O_RDONLY;if (funcArg.GetArgc() >= NARG_CNT::TWO) {auto [succGetFlags, authFlags] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(O_RDONLY);if (!succGetFlags || authFlags < 0) {UniError(EINVAL).ThrowErr(env, "Invalid flags");return nullptr;}flags = static_cast<unsigned int>(authFlags);(void)CommonFunc::ConvertJsFlags(flags);  // 转换JavaScript标志位到系统标志位}// 3. 检查远程URIint fd = -1;if (ModuleRemoteUri::RemoteUri::IsRemoteUri(path.get(), fd, flags)) {return NVal::CreateInt64(env, fd).val_;}// 4. 解析模式参数int32_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;if (funcArg.GetArgc() != NARG_CNT::THREE) {size_t flagsFirst { flags };if ((flagsFirst & O_CREAT) || (flagsFirst & O_TMPFILE)) {UniError(EINVAL).ThrowErr(env, "called with O_CREAT/O_TMPFILE but no mode");return nullptr;}} else {tie(succ, mode) = NVal(env, funcArg.GetArg(NARG_POS::THIRD)).ToInt32(mode);if (!succ) {UniError(EINVAL).ThrowErr(env, "Invalid mode");return nullptr;}}// 5. 执行系统调用fd = open(path.get(), flags, mode);if (fd == -1) {if (errno == ENAMETOOLONG) {UniError(errno).ThrowErr(env, "Filename too long");return nullptr;}UniError(errno).ThrowErr(env);return nullptr;}return NVal::CreateInt64(env, fd).val_;
}
异步打开 (Open::Async)
napi_value Open::Async(napi_env env, napi_callback_info info)
{// 1. 参数解析(与同步版本相同)NFuncArg funcArg(env, info);// ... 参数解析代码 ...// 2. 创建异步工作参数auto arg = make_shared<int32_t>();// 3. 定义执行函数auto cbExec = [path = string(path.get()), flags, mode, arg](napi_env env) -> UniError {return DoOpenExec(path, flags, mode, arg);};// 4. 定义完成回调auto cbComplCallback = [arg](napi_env env, UniError err) -> NVal {if (err) {if (err.GetErrno(ERR_CODE_SYSTEM_POSIX) == ENAMETOOLONG) {return {env, err.GetNapiErr(env, "Filename too long")};}return { env, err.GetNapiErr(env) };}return { NVal::CreateInt64(env, *arg) };};// 5. 调度异步工作NVal thisVar(env, funcArg.GetThisVar());if (argc == NARG_CNT::ONE || (argc == NARG_CNT::TWO &&!NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function))) {return NAsyncWorkPromise(env, thisVar).Schedule("FileIOOpen", cbExec, cbComplCallback).val_;} else {NVal cb(env, funcArg[argc - 1]);return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIOOpen", cbExec, cbComplCallback).val_;}
}

2. 文件读取操作实现

文本读取 (ReadText::Sync)
napi_value ReadText::Sync(napi_env env, napi_callback_info info)
{// 1. 参数解析NFuncArg funcArg(env, info);if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) {UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");return nullptr;}// 2. 获取文件路径auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath();if (!resGetFirstArg) {UniError(EINVAL).ThrowErr(env, "Invalid path");return nullptr;}// 3. 解析读取选项(位置、长度、编码)auto [resGetReadTextArg, position, hasLen, len, encoding] = GetReadTextArg(env, funcArg[NARG_POS::SECOND]);if (!resGetReadTextArg) {UniError(EINVAL).ThrowErr(env, "Invalid option");return nullptr;}// 4. 打开文件并获取文件状态struct stat statbf;FDGuard sfd;sfd.SetFD(open(path.get(), O_RDONLY));if ((!sfd) || (fstat(sfd.GetFD(), &statbf) == -1)) {UniError(errno).ThrowErr(env);return nullptr;}// 5. 验证位置参数if (position > statbf.st_size) {UniError(EINVAL).ThrowErr(env, "Invalid position");return nullptr;}// 6. 计算读取长度len = (!hasLen || len > static_cast<size_t>(statbf.st_size)) ? statbf.st_size : len;// 7. 分配缓冲区std::unique_ptr<char[]> readbuf = std::make_unique<char[]>(len + 1);if (readbuf == nullptr) {UniError(EINVAL).ThrowErr(env, "file is too large");return nullptr;}// 8. 初始化缓冲区if (memset_s(readbuf.get(), len + 1, 0, len + 1) != EOK) {UniError(errno).ThrowErr(env, "dfs mem error");return nullptr;}// 9. 执行读取操作ssize_t ret = 0;if (position >= 0) {ret = pread(sfd.GetFD(), readbuf.get(), len, position);  // 指定位置读取} else {ret = read(sfd.GetFD(), readbuf.get(), len);  // 当前位置读取}if (ret == -1) {UniError(EINVAL).ThrowErr(env, "Invalid read file");return nullptr;}// 10. 返回UTF-8字符串return NVal::CreateUTF8String(env, readbuf.get(), ret).val_;
}

3. 流操作实现

流写入 (StreamNExporter::WriteSync)
napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info info)
{// 1. 参数解析NFuncArg funcArg(env, info);if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) {UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");return nullptr;}// 2. 获取流实体bool succ = false;FILE *filp = nullptr;auto streamEntity = NClass::GetEntityOf<StreamEntity>(env, funcArg.GetThisVar());if (!streamEntity || !streamEntity->fp) {UniError(EBADF).ThrowErr(env, "Stream may has been closed");return nullptr;} else {filp = streamEntity->fp.get();}// 3. 解析写入参数void *buf = nullptr;size_t len = 0;int64_t position = -1;unique_ptr<char[]> bufGuard = nullptr;tie(succ, bufGuard, buf, len, position) =CommonFunc::GetWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]);if (!succ) {return nullptr;}// 4. 定位文件位置(如果指定了位置)if (position >= 0 && (fseek(filp, static_cast<long>(position), SEEK_SET) == -1)) {UniError(errno).ThrowErr(env);return nullptr;}// 5. 执行写入操作size_t writeLen = fwrite(buf, 1, len, filp);if ((writeLen == 0) && (writeLen != len)) {UniError(errno).ThrowErr(env);return nullptr;}// 6. 返回实际写入长度return NVal::CreateInt64(env, writeLen).val_;
}
流读取 (StreamNExporter::ReadSync)
napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info info)
{// 1. 参数解析和流实体获取NFuncArg funcArg(env, info);// ... 参数解析代码 ...// 2. 解析读取参数void *buf = nullptr;size_t len = 0;int64_t pos = -1;tie(succ, buf, len, pos, ignore) =CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]);if (!succ) {return nullptr;}// 3. 定位文件位置if (pos >= 0 && (fseek(filp, static_cast<long>(pos), SEEK_SET) == -1)) {UniError(errno).ThrowErr(env);return nullptr;}// 4. 执行读取操作size_t actLen = fread(buf, 1, len, filp);if ((actLen != len && !feof(filp)) || ferror(filp)) {UniError(errno).ThrowErr(env);}// 5. 返回实际读取长度return NVal::CreateInt64(env, actLen).val_;
}

4. 目录操作实现

目录读取 (DirNExporter::ReadSync)
napi_value DirNExporter::ReadSync(napi_env env, napi_callback_info info)
{// 1. 参数解析NFuncArg funcArg(env, info);if (!funcArg.InitArgs(NARG_CNT::ZERO)) {UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");return nullptr;}// 2. 获取目录实体DirEntity *dirEntity = GetDirEntity(env, info);if (!dirEntity || !dirEntity->dir_) {UniError(EBADF).ThrowErr(env, "Dir has been closed yet");return nullptr;}DIR *dir = dirEntity->dir_.get();// 3. 读取目录条目struct dirent tmpDirent;{lock_guard(dirEntity->lock_);  // 线程安全保护errno = 0;dirent *res = nullptr;do {res = readdir(dir);if (res == nullptr && errno) {UniError(errno).ThrowErr(env);return nullptr;} else if (res == nullptr) {return NVal::CreateUndefined(env).val_;  // 目录结束} else if (string(res->d_name) == "." || string(res->d_name) == "..") {continue;  // 跳过当前目录和父目录} else {if (EOK != memcpy_s(&tmpDirent, sizeof(dirent), res, res->d_reclen)) {UniError(errno).ThrowErr(env);return nullptr;}break;}} while (true);}// 4. 创建Dirent对象napi_value objDirent = NClass::InstantiateClass(env, DirentNExporter::className_, {});if (!objDirent) {return nullptr;}// 5. 设置目录条目数据auto direntEntity = NClass::GetEntityOf<DirentEntity>(env, objDirent);if (!direntEntity) {return nullptr;}direntEntity->dirent_ = tmpDirent;return objDirent;
}
目录文件列表 (DirNExporter::ListFileSync)
napi_value DirNExporter::ListFileSync(napi_env env, napi_callback_info info)
{// 1. 参数解析NFuncArg funcArg(env, info);if (!funcArg.InitArgs(NARG_CNT::ONE)) {UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");return nullptr;}// 2. 获取目录实体和列表数量auto dirEntity = CheckDirEntity(env, funcArg.GetThisVar());if (!dirEntity) {return nullptr;}auto [succ, listNum] = ParseJsListNum(env, funcArg[NARG_POS::FIRST]);if (!succ) {UniError(EINVAL).ThrowErr(env, "Invalid listNum");return nullptr;}// 3. 读取目录条目列表vector<dirent> dirents;{lock_guard(dirEntity->lock_);dirent *res = nullptr;int listCount = 0;auto dir = dirEntity->dir_.get();do {errno = 0;res = readdir(dir);if (res == nullptr && errno) {UniError(errno).ThrowErr(env);return nullptr;} else if (res == nullptr) {break;  // 目录结束} else if (string(res->d_name) == "." || string(res->d_name) == "..") {continue;  // 跳过特殊目录} else {dirents.push_back(*res);listCount++;}} while (listCount < listNum || listNum == 0);  // 按数量限制或全部读取}// 4. 转换为JavaScript数组return DoListFileVector2NV(env, dirents);
}

5. 异步操作实现机制

异步工作调度
// 异步操作的基本模式
napi_value SomeAsyncFunction(napi_env env, napi_callback_info info)
{// 1. 参数解析NFuncArg funcArg(env, info);// ... 参数解析 ...// 2. 定义执行函数(在工作线程中运行)auto cbExec = [captured_vars](napi_env env) -> UniError {// 执行实际的I/O操作int result = some_system_call();if (result == -1) {return UniError(errno);}return UniError(ERRNO_NOERR);};// 3. 定义完成回调(在主线程中运行)auto cbCompl = [captured_vars](napi_env env, UniError err) -> NVal {if (err) {return { env, err.GetNapiErr(env) };} else {// 返回结果return NVal::CreateSomeValue(env, result);}};// 4. 调度异步工作NVal thisVar(env, funcArg.GetThisVar());if (is_promise_mode) {return NAsyncWorkPromise(env, thisVar).Schedule("ProcedureName", cbExec, cbCompl).val_;} else {NVal cb(env, funcArg[callback_index]);return NAsyncWorkCallback(env, thisVar, cb).Schedule("ProcedureName", cbExec, cbCompl).val_;}
}

6. 错误处理机制

统一错误处理
// UniError类的使用
if (some_operation_failed) {if (errno == ENAMETOOLONG) {UniError(errno).ThrowErr(env, "Filename too long");} else {UniError(errno).ThrowErr(env);}return nullptr;
}
参数验证
// 参数数量验证
if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) {UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");return nullptr;
}// 参数类型验证
auto [succ, value] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
if (!succ || value < 0) {UniError(EINVAL).ThrowErr(env, "Invalid parameter");return nullptr;
}

使用示例

基本文件操作

import fileio from '@ohos.fileio';// 打开文件
let file = fileio.openSync('/path/to/file', fileio.OpenMode.READ_ONLY);// 读取文件
let buffer = new ArrayBuffer(1024);
fileio.readSync(file.fd, buffer);// 关闭文件
fileio.closeSync(file.fd);

目录操作

import fileio from '@ohos.fileio';// 打开目录
let dir = fileio.opendirSync('/path/to/directory');// 读取目录条目
let dirent = fileio.readSync(dir.fd);// 列出文件
let files = fileio.listFileSync(dir.fd);// 关闭目录
fileio.closedirSync(dir.fd);

流操作

import fileio from '@ohos.fileio';// 创建流
let stream = fileio.createStream('/path/to/file', 'r+');// 写入数据
let data = new TextEncoder().encode('Hello World');
fileio.writeSync(stream.fd, data);// 刷新流
fileio.flushSync(stream.fd);// 关闭流
fileio.closeSync(stream.fd);

性能优化

1. 异步I/O

大量使用异步I/O操作,避免阻塞主线程:

static napi_value Async(napi_env env, napi_callback_info info) {// 异步操作实现napi_work work;napi_create_async_work(env, nullptr, resource_name, Execute, Complete, &work);napi_queue_async_work(env, work);
}

2. 缓冲区管理

使用ArrayBuffer进行高效的数据传输:

tie(succ, buf, bufLen) = txt.ToArraybuffer();

3. 参数验证

在C++层面进行参数验证,减少JavaScript层的开销:

if (!succ || position < 0) {UniError(EINVAL).ThrowErr(env, "Invalid parameter");return { false, nullptr, 0, position, offset };
}

安全考虑

1. 路径验证

所有路径操作都进行安全验证:

tie(succ, src, ignore) = NVal(env, srcPath).ToUTF8StringPath();

2. 权限检查

文件操作前进行权限检查:

static napi_value AccessSync(napi_env env, napi_callback_info info);

3. 资源管理

使用RAII模式确保资源正确释放:

~AsyncIOWrtieArg() = default;

总结

mod_fileio模块是OpenHarmony文件管理API的核心组件,提供了完整、高效、安全的文件I/O操作功能。其设计具有以下特点:

  1. 模块化设计:清晰的目录结构和职责分离
  2. 版本兼容:提供标准版本和V9版本
  3. 性能优化:异步I/O和高效的内存管理
  4. 安全可靠:完善的错误处理和权限控制
  5. 易于使用:统一的API设计和丰富的功能支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/95845.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/95845.shtml
英文地址,请注明出处:http://en.pswp.cn/web/95845.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js逆向Webpack模块加载机制解析:从数组到JSONP

1. 概述 Webpack作为现代前端开发中最流行的模块打包工具&#xff0c;其模块加载机制值得深入理解。本文将解析Webpack的几种模块加载方式&#xff0c;包括数组形式、键值对形式和JSONP动态加载。只有理解了它的相关加载机制&#xff0c;我们才可以进行逆向工作。 2. 数组形式的…

Joplin-解决 Node.js 中 “digital envelope routines::unsupported“ 错误

解决 Node.js 中 “digital envelope routines::unsupported” 错误 在使用 Webpack 构建 Joplin 插件时&#xff0c;你可能会遇到 error:0308010C:digital envelope routines::unsupported 错误。这个错误看起来很复杂&#xff0c;但实际上有明确的原因和解决方案。 错误原因…

UE5 UAT

通过UAT 打包的流程&#xff0c;先整理这么点入口// Engine\Source\Programs\AutomationTool\Program.cs /// <summary> /// Main entry point /// </summary> public partial class Program {public static async Task<int> Main(string[] Arguments){Logge…

Python带状态生成器完全指南:从基础到高并发系统设计

引言&#xff1a;状态化生成器的核心价值在复杂系统开发中&#xff0c;带状态的生成器是处理复杂逻辑的核心工具。根据2024年Python开发者调查报告&#xff1a;78%的状态机实现使用带状态生成器85%的数据管道依赖状态化生成器92%的并发系统需要状态管理65%的算法优化通过状态化…

Python元组:不可变但灵活的数据容器

Python元组&#xff1a;不可变但灵活的数据容器 元组(tuple)是Python中一种不可变(immutable)但功能灵活的有序集合数据类型&#xff0c;具有以下核心特性&#xff1a;一、基本特性 不可变性‌&#xff1a;创建后不能修改元素&#xff08;增删改操作均不允许&#xff09; 有序存…

FastGPT源码解析 Agent 大模型对接接口和使用详解

FastGPT 大模型对接核心代码分析 核心架构概览 FastGPT 采用统一模型抽象层设计&#xff0c;通过标准化接口对接多种大模型&#xff0c;支持 LLM、Embedding、ReRank、TTS、STT 等多种 AI 能力。 支持各种大模型能力的配置&#xff0c;包括本地ollama、各个AI云厂商的API接入配…

AI Compass前沿速览:Kimi K2、InfinityHuman-AI数字人、3D-AI桌面伴侣、叠叠社–AI虚拟陪伴

AI Compass前沿速览&#xff1a;Kimi K2、InfinityHuman-AI数字人、3D-AI桌面伴侣、叠叠社–AI虚拟陪伴 AI-Compass 致力于构建最全面、最实用、最前沿的AI技术学习和实践生态&#xff0c;通过六大核心模块的系统化组织&#xff0c;为不同层次的学习者和开发者提供从完整学习路…

如何下载B站视频,去水印,翻译字幕

首先先来看下如何下载B站视频及音频工具&#xff1a;手机下载视频打开文件管理器&#xff0c;找到video.m4s和audio.m4s两个文件更改文件后缀名第一步到此为止然后我们再来看一下如何去水印&#xff0c;去字幕工具&#xff1a;剪映导入视频选择蒙版 > 镜面点击反转点击基础&…

用 Cursor AI 快速开发你的第一个编程小程序

Cursor AI 作为新一代 AI 编程助手&#xff0c;集成了代码补全、智能调试、自动生成等强大功能&#xff0c;非常适合用来开发小型应用或小程序。本文我将手把手带你用 Cursor AI 开发一个简单的天气查询小程序&#xff0c;并在文中推荐一门实用的商业变现课程&#xff0c;助你走…

MacOS 使用 luarocks+wrk+luajit

MacOS 使用 luarockswrkluajit luarocks 默认使用的是 lua 5.4 版本&#xff0c;一些工具&#xff0c;例如 wrk 使用的 lua 5.1&#xff0c;那么 luarocks 在安装依赖的时候就需要指定 lua 5.1。 luarocks config 配置 lua 5.1 请确保已经安装了 lua5.1 或者 luajit&#xff0c…

PostgreSQL18-FDW连接的 SCRAM 直通身份验证

PostgreSQL18-FDW连接的 SCRAM 直通身份验证 PostgreSQL 18 为使用 postgres_fdw 或 dblink_fdw 的人带来了很好的改进&#xff1a;SCRAM 直通身份验证。设置外部服务器连接时&#xff0c;您不再需要在“用户映射”选项中存储纯文本密码。 这是实现它的提交&#xff1a; commit…

“卧槽,系统又崩了!”——别慌,这也许是你看过最通俗易懂的分布式入门

在分布式系统中&#xff0c;有效应对节点故障、网络分区延迟和数据一致性等挑战至关重要。本文将剖析保障分布式系统可靠性的核心机制&#xff1a;数据分片实现水平扩展&#xff0c;冗余副本保障数据高可用&#xff0c;租约&#xff08;Lease&#xff09;机制优化节点状态共识与…

【代码随想录算法训练营——Day4】链表——24.两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题02.07.链表相交、142.环形链表II

LeetCode题目链接 https://leetcode.cn/problems/swap-nodes-in-pairs/ https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/ https://leetcode.cn/problems/linked-list-cycle…

C#中一段程序类比博图

using system //博图中要使用自带指令库&#xff0c;指令库名称叫systemnamespace Simple//博图建立程序&#xff0c;分诊断文件夹&#x1f4c2;&#xff0c;vision文件夹&#xff0c;通讯Db文件夹&#x1f4c2;等等&#xff0c;simple类似博图中的文件夹名称{class Program//程…

vue飞自在酒店管理系统(代码+数据库+LW)

摘 要 近年来&#xff0c;随着科技的迅猛进步和经济全球化的深入发展&#xff0c;互联网技术正以前所未有的速度提升社会综合发展的效能。这一技术的影响力已渗透到各行各业&#xff0c;其中&#xff0c;飞自在酒店管理系统在互联网时代背景下扮演着举足轻重的角色。信息管理…

2025年统计与数据分析领域专业认证发展指南

在数据驱动决策日益重要的背景下&#xff0c;专业认证作为提升统计学和数据分析能力的一种方式&#xff0c;受到越来越多从业者的关注。本文基于行业发展趋势&#xff0c;分析6个相关领域的专业资格认证&#xff0c;为专业人士提供参考。一、数据分析能力认证含金量CDA数据分析…

激光频率梳 3D 轮廓测量 - 油路板的凹槽深度和平面度测量

一、引言油路板作为液压系统核心部件&#xff0c;其凹槽深度与平面度精度直接影响油液流动特性与密封性能。传统测量方法在面对复杂油路结构时存在效率低、精度不足等问题。激光频率梳 3D 轮廓测量技术凭借时频基准优势&#xff0c;为油路板关键参数测量提供了新路径&#xff0…

七彩喜微高压氧舱:科技与体验的双重革新,重新定义家用氧疗新标杆

在高压氧舱市场竞争日益激烈的今天&#xff0c;七彩喜微高压氧舱凭借其独特的技术创新、极致的用户体验和贴心的服务生态&#xff0c;在众多品牌中脱颖而出。它不仅是一台设备&#xff0c;更是一个“懂你需求、护你健康”的智能健康伙伴。对比其他品牌&#xff0c;七彩喜的优势…

[光学原理与应用-418]:非线性光学 - 数学中的线性函数与非线性函数

线性函数与非线性函数是数学和工程领域中描述变量关系的基础工具&#xff0c;二者在定义、性质、图像特征及应用场景上存在本质差异。以下从核心概念、数学特性、图像对比、应用场景及实际案例五个维度展开详细分析&#xff1a;一、核心概念&#xff1a;线性 vs 非线性线性函数…

前端登录鉴权详解

1.cookie-session1. cookiecookie简单来说就是浏览器客户端在请求时会携带的一个字段数据&#xff0c;常用与保存当前用户状态并在请求时携带给服务端验证。2. sessionsession简单来说就是服务单对于每一个用户生成一个用户会话标识session /session id&#xff0c;并返回给客户…