欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ 檢測文件大小和文件傳輸?shù)姆椒ㄊ纠斀?/h1>
 更新時間:2025年06月21日 11:16:21   作者:W1E  
文章介紹了在C/C++中獲取文件大小的三種方法,推薦使用stat()函數(shù),并詳細(xì)說明了如何設(shè)計(jì)一次性發(fā)送壓縮包的結(jié)構(gòu)體及傳輸流程,包含CRC校驗(yàn)和自動解壓邏輯,同時提供代碼模板生成建議,支持跨平臺及多種傳輸協(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)兼容限制(大文件時注意 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;
}
  • ? 簡潔
  • ? 跨平臺(Linux/Unix)
  • ? 不依賴文件流,不怕破壞文件位置

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

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

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

? 明白了 —— 你要實(shí)現(xiàn)的是 一次性發(fā)送整個壓縮包文件(如 .zip,那么結(jié)構(gòu)體就可以設(shè)計(jì)得更簡單,不需要 offset / 分包機(jī)制,只傳一整個文件內(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;             // 指令編號,比如 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ā)送整個結(jié)構(gòu)體(例如通過 USB FunctionFS 或 UNIX socket)

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

  • 接收整個結(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)動態(tài)申請
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) + 解壓自動調(diào)用邏輯

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

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

? 功能說明

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

? 公共結(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);
    // 自動解壓
    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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • opencv檢測直線方法之形態(tài)學(xué)方法

    opencv檢測直線方法之形態(tài)學(xué)方法

    這篇文章主要為大家詳細(xì)介紹了opencv檢測直線方法之形態(tài)學(xué)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C++實(shí)現(xiàn)MyString的示例代碼

    C++實(shí)現(xiàn)MyString的示例代碼

    本文主要介紹了C++實(shí)現(xiàn)MyString的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C語言實(shí)現(xiàn)三子棋

    C語言實(shí)現(xiàn)三子棋

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)三子棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • C語言輸出旋轉(zhuǎn)后數(shù)組中的最小數(shù)元素的算法原理與實(shí)例

    C語言輸出旋轉(zhuǎn)后數(shù)組中的最小數(shù)元素的算法原理與實(shí)例

    這篇文章主要介紹了C語言輸出旋轉(zhuǎn)后數(shù)組中的最小數(shù)元素的算法原理與實(shí)例,數(shù)組旋轉(zhuǎn)就是把開頭的幾個指定的元素放到數(shù)組的末尾,需要的朋友可以參考下
    2016-03-03
  • C語言實(shí)戰(zhàn)之紙牌游戲

    C語言實(shí)戰(zhàn)之紙牌游戲

    這篇文章主要為大家介紹了通過C語言實(shí)現(xiàn)的紙牌游戲的示例代碼,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定的幫助,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2021-12-12
  • C++中::SHCreateDirectoryEx函數(shù)使用方法

    C++中::SHCreateDirectoryEx函數(shù)使用方法

    ::SHCreateDirectoryEx用于創(chuàng)建多級目錄,類似于mkdir -p命令,本文主要介紹了C++中::SHCreateDirectoryEx函數(shù)使用方法,具有一定的參考價值,感興趣的可以了解一下
    2025-03-03
  • C++中4種強(qiáng)制類型轉(zhuǎn)換的區(qū)別詳析

    C++中4種強(qiáng)制類型轉(zhuǎn)換的區(qū)別詳析

    這篇文章主要給大家介紹了關(guān)于C++中4種強(qiáng)制類型轉(zhuǎn)換區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 常用的C++標(biāo)準(zhǔn)庫頭文件小結(jié)

    常用的C++標(biāo)準(zhǔn)庫頭文件小結(jié)

    C++標(biāo)準(zhǔn)庫定義了一系列函數(shù)、宏和對象,以實(shí)現(xiàn)跨團(tuán)隊(duì)、跨平臺的高效且具有卓越性能的標(biāo)準(zhǔn)化 C++ 代碼, 本文介紹常用的C++標(biāo)準(zhǔn)庫頭文件,需要的朋友可以參考下
    2023-11-11
  • 基于C++實(shí)現(xiàn)TCP聊天室功能

    基于C++實(shí)現(xiàn)TCP聊天室功能

    這篇文章主要為大家詳細(xì)介紹了基于C++實(shí)現(xiàn)TCP聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • opencv實(shí)現(xiàn)圖形輪廓檢測

    opencv實(shí)現(xiàn)圖形輪廓檢測

    這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)圖形輪廓檢測,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04

最新評論