最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 檢測文件大小和文件傳輸?shù)姆椒ㄊ纠斀?/h1>
 更新時(shí)間:2025年06月21日 11:16:21   作者:W1E  
文章介紹了在C/C++中獲取文件大小的三種方法,推薦使用stat()函數(shù),并詳細(xì)說明了如何設(shè)計(jì)一次性發(fā)送壓縮包的結(jié)構(gòu)體及傳輸流程,包含CRC校驗(yàn)和自動(dòng)解壓邏輯,同時(shí)提供代碼模板生成建議,支持跨平臺(tái)及多種傳輸協(xié)議(如USB/Socket)的集成方案,感興趣的朋友一起看看吧

檢測文件的大小

你可以通過標(biāo)準(zhǔn) C/C++ 的文件 API 很方便地獲取文件的字節(jié)大小,以下是幾種常用方法:

? 方法一:使用 stat() 函數(shù)(推薦)

#include <sys/stat.h>
#include <stdio.h>
off_t get_file_size(const char* file_path) {
    struct stat st;
    if (stat(file_path, &st) == 0) {
        return st.st_size;  // 返回字節(jié)數(shù)
    } else {
        perror("stat failed");
        return -1;
    }
}

? 用法示例:

const char* path = "myfile.zip";
off_t size = get_file_size(path);
printf("File size = %ld bytes\n", size);

? 方法二:使用 fseek() / ftell()

long get_file_size_fp(FILE* fp) {
    long current = ftell(fp);   // 記錄當(dāng)前讀寫位置
    fseek(fp, 0, SEEK_END);     // 跳到末尾
    long size = ftell(fp);      // 獲取位置
    fseek(fp, current, SEEK_SET); // 恢復(fù)位置
    return size;
}

?? 注意:

  • ftell() 返回的是 long,有系統(tǒng)兼容限制(大文件時(shí)注意 off_t
  • 推薦用于你已經(jīng)打開了文件的場景(不適合只用路徑的情況)

? 方法三:C++17 的 std::filesystem(僅限 C++17 及以上)

#include <filesystem>
namespace fs = std::filesystem;
uintmax_t get_file_size(const std::string& path) {
    return fs::file_size(path);
}

? 總結(jié):推薦使用 stat()

off_t get_file_size(const char* path) {
    struct stat st;
    return stat(path, &st) == 0 ? st.st_size : -1;
}
  • ? 簡潔
  • ? 跨平臺(tái)(Linux/Unix)
  • ? 不依賴文件流,不怕破壞文件位置

需要我一并把“讀取文件內(nèi)容 + 填充結(jié)構(gòu)體 + 發(fā)送”整合成一個(gè)發(fā)送函數(shù)嗎?例如:

bool send_file(const char* src_path, const char* dst_path, int fd);

我可以直接幫你寫好。是否繼續(xù)?

? 明白了 —— 你要實(shí)現(xiàn)的是 一次性發(fā)送整個(gè)壓縮包文件(如 .zip,那么結(jié)構(gòu)體就可以設(shè)計(jì)得更簡單,不需要 offset / 分包機(jī)制,只傳一整個(gè)文件內(nèi)容。

? 簡潔版結(jié)構(gòu)體設(shè)計(jì):一次性發(fā)送文件

#define MAX_FILENAME_LEN 128
#define MAX_FILEPATH_LEN 256
#define MAX_FILEDATA_LEN (4 * 1024 * 1024)  // 例如最多傳 4MB,可自定義
struct FilePacket {
    uint32_t cmd_id;             // 指令編號(hào),比如 0x01 表示發(fā)送文件
    uint32_t file_size;          // 文件實(shí)際大小
    uint32_t file_crc32;         // 文件整體 CRC32,用于校驗(yàn)
    char     file_name[MAX_FILENAME_LEN];   // 文件名(如 data.zip)
    char     file_path[MAX_FILEPATH_LEN];   // 保存路徑(如 /tmp/data.zip)
    uint8_t  file_data[MAX_FILEDATA_LEN];   // 實(shí)際文件內(nèi)容
};

? 使用流程說明

1. PC 端

  • 讀取壓縮包內(nèi)容到 file_data
  • 計(jì)算文件實(shí)際大小和 CRC32
  • 設(shè)置目標(biāo)保存路徑
  • 一次性發(fā)送整個(gè)結(jié)構(gòu)體(例如通過 USB FunctionFS 或 UNIX socket)

2. 嵌入式設(shè)備端

  • 接收整個(gè)結(jié)構(gòu)體
  • 先校驗(yàn) file_size 和 file_crc32
  • 保存 file_data[0..file_size-1] 到 file_path
  • 成功后用 unzip 或 tar 解壓

?? 注意事項(xiàng)

項(xiàng)目建議
最大文件大小控制在 MAX_FILEDATA_LEN 之內(nèi)(如 4MB)
傳輸協(xié)議USB、UNIX Socket、Pipe 等都可
內(nèi)存分配接收端需要足夠大緩沖區(qū),否則應(yīng)動(dòng)態(tài)申請(qǐng)
CRC校驗(yàn)推薦使用 CRC32(或 MD5)校驗(yàn)完整性

? 示例:文件接收邏輯(偽代碼)

FilePacket pkt;
recv(fd, &pkt, sizeof(FilePacket), 0);
// 校驗(yàn)
if (pkt.file_crc32 != calc_crc32(pkt.file_data, pkt.file_size)) {
    fprintf(stderr, "CRC mismatch\n");
    return -1;
}
// 保存文件
FILE *fp = fopen(pkt.file_path, "wb");
fwrite(pkt.file_data, 1, pkt.file_size, fp);
fclose(fp);
// 解壓
char cmd[512];
sprintf(cmd, "unzip -o %s -d /tmp/unpack_dir/", pkt.file_path);
system(cmd);

? 總結(jié):你的最終結(jié)構(gòu)體如下

struct FilePacket {
    uint32_t cmd_id;             // CMD_SEND_FILE
    uint32_t file_size;
    uint32_t file_crc32;
    char     file_name[128];
    char     file_path[256];
    uint8_t  file_data[4 * 1024 * 1024];  // 最大4MB壓縮包
};

非常適合你現(xiàn)在這種 一發(fā)搞定、接收即解壓 的模式。

如果你需要,我可以:

  • 幫你寫出 C++ 的發(fā)送/接收代碼模板
  • 提供 CRC32 實(shí)現(xiàn)
  • 添加壓縮包校驗(yàn) + 解壓自動(dòng)調(diào)用邏輯

是否需要我給你生成一套完整函數(shù)代碼?

好的,我們來構(gòu)建一套完整的一次性發(fā)送壓縮包文件的文件傳輸代碼模板,包括:

? 功能說明

  • PC 端:發(fā)送 .zip 壓縮包,讀取 + CRC32 校驗(yàn) + 封裝發(fā)送
  • 設(shè)備端:接收文件結(jié)構(gòu)體 → CRC 校驗(yàn) → 寫入文件 → 自動(dòng)解壓

? 公共結(jié)構(gòu)體定義(FilePacket)

#define MAX_FILENAME_LEN 128
#define MAX_FILEPATH_LEN 256
#define MAX_FILEDATA_LEN (4 * 1024 * 1024)  // 最多 4MB,可根據(jù)內(nèi)存調(diào)整
struct FilePacket {
    uint32_t cmd_id;            // CMD_SEND_FILE = 0x01
    uint32_t file_size;
    uint32_t file_crc32;
    char     file_name[MAX_FILENAME_LEN];
    char     file_path[MAX_FILEPATH_LEN];
    uint8_t  file_data[MAX_FILEDATA_LEN];
};

? CRC32 實(shí)現(xiàn)(簡潔版本)

uint32_t crc32(const uint8_t* data, size_t len) {
    uint32_t crc = 0xFFFFFFFF;
    for (size_t i = 0; i < len; ++i) {
        crc ^= data[i];
        for (int j = 0; j < 8; ++j)
            crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1));
    }
    return ~crc;
}

? 發(fā)送端函數(shù)(PC)

bool send_file(int sock_fd, const char* src_path, const char* dst_path) {
    FILE* fp = fopen(src_path, "rb");
    if (!fp) {
        perror("open src file");
        return false;
    }
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    if (file_size <= 0 || file_size > MAX_FILEDATA_LEN) {
        fprintf(stderr, "Invalid file size: %ld\n", file_size);
        fclose(fp);
        return false;
    }
    FilePacket pkt = {};
    pkt.cmd_id = 0x01;
    pkt.file_size = file_size;
    fread(pkt.file_data, 1, file_size, fp);
    fclose(fp);
    pkt.file_crc32 = crc32(pkt.file_data, file_size);
    strncpy(pkt.file_name, basename((char*)src_path), MAX_FILENAME_LEN);
    strncpy(pkt.file_path, dst_path, MAX_FILEPATH_LEN);
    if (send(sock_fd, &pkt, sizeof(pkt), 0) != sizeof(pkt)) {
        perror("send failed");
        return false;
    }
    printf("Send file OK: %s (%ld bytes)\n", src_path, file_size);
    return true;
}

? 接收端函數(shù)(設(shè)備)

bool recv_file(int sock_fd) {
    FilePacket pkt;
    ssize_t n = recv(sock_fd, &pkt, sizeof(pkt), 0);
    if (n != sizeof(pkt)) {
        perror("recv failed or incomplete");
        return false;
    }
    uint32_t calc_crc = crc32(pkt.file_data, pkt.file_size);
    if (calc_crc != pkt.file_crc32) {
        fprintf(stderr, "CRC32 mismatch! recv=0x%08x, calc=0x%08x\n", pkt.file_crc32, calc_crc);
        return false;
    }
    FILE* fp = fopen(pkt.file_path, "wb");
    if (!fp) {
        perror("open write file");
        return false;
    }
    fwrite(pkt.file_data, 1, pkt.file_size, fp);
    fclose(fp);
    printf("File received: %s (%u bytes), saved to %s\n",
        pkt.file_name, pkt.file_size, pkt.file_path);
    // 自動(dòng)解壓
    char cmd[512];
    snprintf(cmd, sizeof(cmd), "unzip -o %s -d /tmp/unpack_dir/", pkt.file_path);
    int ret = system(cmd);
    if (ret != 0) {
        fprintf(stderr, "unzip failed\n");
        return false;
    }
    printf("Unzip complete.\n");
    return true;
}

? 示例調(diào)用方式

PC 端發(fā)送:

send_file(sock_fd, "./update.zip", "/tmp/recv.zip");

設(shè)備端接收并解壓:

recv_file(sock_fd);

?? 后續(xù)建議擴(kuò)展

功能可做法
ACK/NACK接收端校驗(yàn)成功后返回 ACK
分包大文件適配 chunk 傳輸結(jié)構(gòu)體
解壓失敗回滾解壓前備份舊文件
解壓路徑配置結(jié)構(gòu)體中加入 unpack_path

是否需要我?guī)湍愦虬赏暾こ棠夸洠◣?Makefile/CMake)或?qū)拥?FunctionFS 項(xiàng)目中?你也可以告訴我你當(dāng)前的傳輸通道(USB FunctionFS / Socket / Pipe)我?guī)湍愣ㄖ萍?。是否繼續(xù)?

到此這篇關(guān)于C++ 檢測文件大小和文件傳輸?shù)姆椒ㄊ纠斀獾奈恼戮徒榻B到這了,更多相關(guān)C++ 檢測文件大小和文件傳輸內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++?OpenCV實(shí)現(xiàn)白平衡之完美反射算法

    C++?OpenCV實(shí)現(xiàn)白平衡之完美反射算法

    完美反射算法是白平衡各種算法中較常見的一種,比灰度世界算法更優(yōu)。本文將利用C++和OpenCV實(shí)現(xiàn)白平衡中的完美反射算法,需要的可以參考一下
    2022-05-05
  • 最新評(píng)論

    陇西县| 鲜城| 开江县| 五指山市| 蓬溪县| 东方市| 池州市| 库尔勒市| 望城县| 太仆寺旗| 灵宝市| 温泉县| 宁蒗| 墨竹工卡县| 马龙县| 大化| 和政县| 佛山市| 岳阳县| 云阳县| 乳山市| 溧阳市| 抚宁县| 乌兰县| 灵璧县| 离岛区| 东阿县| 阳曲县| 太康县| 普宁市| 黎川县| 澄迈县| 静宁县| 柘城县| 芒康县| 达孜县| 淮北市| 红桥区| 汽车| 康保县| 海盐县|