【OpenHarmony文件管理子系統】文件訪問接口mod_fileio解析

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;并返回給客戶…