C++ 檢測文件大小和文件傳輸

檢測文件的大小

你可以通過標準 C/C++ 的文件 API 很方便地獲取文件的字節大小,以下是幾種常用方法:


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

#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;  // 返回字節數} 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);   // 記錄當前讀寫位置fseek(fp, 0, SEEK_END);     // 跳到末尾long size = ftell(fp);      // 獲取位置fseek(fp, current, SEEK_SET); // 恢復位置return size;
}

?? 注意:

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

? 方法三: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);
}

? 總結:推薦使用 stat()

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

需要我一并把“讀取文件內容 + 填充結構體 + 發送”整合成一個發送函數嗎?例如:

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

我可以直接幫你寫好。是否繼續?

? 明白了 —— 你要實現的是 一次性發送整個壓縮包文件(如 .zip,那么結構體就可以設計得更簡單,不需要 offset / 分包機制,只傳一整個文件內容。


? 簡潔版結構體設計:一次性發送文件

#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 表示發送文件uint32_t file_size;          // 文件實際大小uint32_t file_crc32;         // 文件整體 CRC32,用于校驗char     file_name[MAX_FILENAME_LEN];   // 文件名(如 data.zip)char     file_path[MAX_FILEPATH_LEN];   // 保存路徑(如 /tmp/data.zip)uint8_t  file_data[MAX_FILEDATA_LEN];   // 實際文件內容
};

? 使用流程說明

1. PC 端

  • 讀取壓縮包內容到 file_data
  • 計算文件實際大小和 CRC32
  • 設置目標保存路徑
  • 一次性發送整個結構體(例如通過 USB FunctionFS 或 UNIX socket)

2. 嵌入式設備端

  • 接收整個結構體
  • 先校驗 file_sizefile_crc32
  • 保存 file_data[0..file_size-1]file_path
  • 成功后用 unziptar 解壓

🧠 注意事項

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

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

FilePacket pkt;
recv(fd, &pkt, sizeof(FilePacket), 0);// 校驗
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);

? 總結:你的最終結構體如下

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

非常適合你現在這種 一發搞定、接收即解壓 的模式。


如果你需要,我可以:

  • 幫你寫出 C++ 的發送/接收代碼模板
  • 提供 CRC32 實現
  • 添加壓縮包校驗 + 解壓自動調用邏輯

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

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


? 功能說明

  • PC 端:發送 .zip 壓縮包,讀取 + CRC32 校驗 + 封裝發送
  • 設備端:接收文件結構體 → CRC 校驗 → 寫入文件 → 自動解壓

? 公共結構體定義(FilePacket)

#define MAX_FILENAME_LEN 128
#define MAX_FILEPATH_LEN 256
#define MAX_FILEDATA_LEN (4 * 1024 * 1024)  // 最多 4MB,可根據內存調整struct FilePacket {uint32_t cmd_id;            // CMD_SEND_FILE = 0x01uint32_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 實現(簡潔版本)

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;
}

? 發送端函數(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;
}

? 接收端函數(設備)

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;
}

? 示例調用方式

PC 端發送:

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

設備端接收并解壓:

recv_file(sock_fd);

🧱 后續建議擴展

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

是否需要我幫你打包成完整工程目錄(帶 Makefile/CMake)或對接到 FunctionFS 項目中?你也可以告訴我你當前的傳輸通道(USB FunctionFS / Socket / Pipe)我幫你定制集成。是否繼續?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85581.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85581.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85581.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu 中修改網卡 IP

在 Ubuntu 中修改網卡 IP 地址可以通過以下方法實現&#xff0c;具體取決于你使用的網絡管理工具&#xff08;如 netplan、ifconfig/ip 命令或傳統 interfaces 文件&#xff09;。以下是常見方法&#xff1a; 方法 1&#xff1a;使用 netplan&#xff08;Ubuntu 17.10 及更新版…

記錄學習three.js 為什么 .glTF 是更適合 Web 的 3D 模型格式?——從 .OBJ 到 .glTF 的轉變?

在上一篇中&#xff0c;我們介紹了如何在 Three.js 中加載 .OBJ 模型。如果你沒看過&#xff0c;建議先閱讀一下基礎內容。然而你很快會發現&#xff0c;.OBJ 雖然入門簡單&#xff0c;卻并不是 Web3D 場景中的最佳格式。 .OBJ 是什么&#xff1f; .OBJ 是最早期的3D交換格式之…

H遞歸函數.go

前言&#xff1a;遞歸函數是一種強大而又充滿魅力的編程技巧。它就像是一面神奇的鏡子&#xff0c;函數在其中能夠調用自身的倒影&#xff0c;從而以一種簡潔而優雅的方式解決許多復雜的問題。 目錄 一、遞歸函數是啥玩意兒 二、遞歸函數的優缺點 優點 缺點 三、遞歸函數…

軟件功能測試的測試標準

一、軟件功能測試行業標準概述 軟件功能測試行業標準是規范軟件測試流程、方法、工具及人員資質的準則&#xff0c;是確保軟件產品的功能性、可靠性、易用性等質量特性符合用戶需求。這些標準不僅為測試人員提供了明確的指導&#xff0c;也為軟件產品的質量控制提供了有力保障。…

EchoEar(喵伴):樂鑫發布與火山引擎扣子聯名 AI 智能體開發板

隨著生成式人工智能技術的快速發展&#xff0c;大語言模型 (LLM) 正逐步成為推動智能設備升級的核心力量。樂鑫科技攜手火山引擎扣子大模型團隊&#xff0c;共同推出智能 AI 開發套件 —— EchoEar&#xff08;喵伴&#xff09;。該套件以端到端開發為核心理念&#xff0c;構建…

圖像特征檢測算法SIFT

SIFT&#xff08;Scale - Invariant Feature Transform&#xff0c;尺度不變特征變換&#xff09;是一種計算機視覺領域的特征提取算法&#xff0c;具有重要的地位和廣泛的應用。 算法原理 構建高斯金字塔 &#xff1a; 為了實現多尺度檢測&#xff0c;SIFT 算法會構建高斯金…

光纖通道收發器:市場洞察、技術演進與未來機遇

一、引言 在數字化浪潮席卷全球的當下&#xff0c;數據存儲與傳輸的需求呈爆發式增長。光纖通道收發器作為高速、可靠數據存儲網絡&#xff08;如存儲區域網絡 SAN&#xff09;中的關鍵組件&#xff0c;發揮著至關重要的作用。它通過光纖實現服務器、存儲設備和交換機之間的數…

candence17.4如何設置兩個焊盤之間在TOP與BOTTOM可以存在兩根線

為什么要走兩根線&#xff1f; 為了過大電流&#xff0c;有時候就需要我們在TOP、BOTTOM兩個面走線&#xff0c;同時開窗&#xff0c;然后通過加錫的方式增加過流能力&#xff1b; 當然由于兩面都有導線&#xff0c;必然會存在過孔&#xff0c;而過孔的過流能力不僅與過孔孔徑…

Dify:參數調節,讓LLM從能用到好用的機制

前言 隨著大語言模型(LLM)在文本生成、智能對話、技術問答等前沿領域的深度滲透&#xff0c;參數精細化調節已成為開發者駕馭 AI 能力的核心必修課。 本文將系統的解釋溫度(Temperature)、核采樣(Top - P)、截斷采樣(Top - K)等關鍵參數的底層作用機制&#xff0c;結合多種場景…

防抖不同的實現

防抖&#xff08;Debounce&#xff09;&#xff1a;在事件被觸發后&#xff0c;延遲一段時間再執行函數。如果在延遲期間事件再次被觸發&#xff0c;則重新計時。常用于搜索框輸入、窗口大小調整等場景。 1.不安裝任何依賴和庫&#xff0c;編寫一個防抖的函數 在utils里面增加…

MySQL 數據庫索引詳解

一、索引是什么&#xff1f;能干嘛&#xff1f; 類比理解&#xff1a;索引就像書的目錄。比如你想查《哈利波特》中 “伏地魔” 出現的頁數&#xff0c;不用逐頁翻書&#xff0c;直接看目錄找關鍵詞就行。數據庫里的索引就是幫你快速找到數據的 “目錄”。 核心作用&#xff…

【620公司工作記錄】

已有數據匯總 好的,完全同意。在編寫新代碼之前,清晰地盤點我們手中已有的“彈藥”是至關重要的一步。 根據您提供的 test/20250610_88_100mm_frame_000.csv 文件頭,我來為您完整地解析一下我們當前擁有的全部數據字段。我們的數據是以“行”為單位組織的,每一行都代表一…

SpringBoot 集成Caffeine實現一級緩存

SpeingBoot 集成Caffeine實現一級緩存使我們經常遇到的場景。今天我們具體分享一下&#xff1a; 首先 Caffeine 作為一級緩存&#xff0c;它是 Spring 5.x 默認的本地緩存實現&#xff0c;性能優于 Guava Cache&#xff0c;且支持過期時間設置。緩存執行的流程圖如下&#xff…

中科米堆3D自動掃描檢測系統三維數字化智能解決方案

3D自動掃描檢測系統基于先進的光學、激光或結構光等測量技術&#xff0c;能夠快速、準確地獲取工件的三維幾何數據。在檢測過程中&#xff0c;系統通過向被測工件投射特定的光模式&#xff0c;利用高分辨率相機捕捉工件表面的反射光信息&#xff0c;再經過復雜的算法處理&#…

Unity3d中使用Mirror進行自定義消息通信

一、服務端&#xff1a; 1.創建服務端腳本MyServer.cs 繼承自NetworkManager類 using Mirror; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class MyServer : NetworkManager {[Header(&quo…

Odoo 18 固定資產管理自動化指南

如何在Odoo 18中實現資產管理自動化 1. 創建資產模型實現資產管理自動化 使用 Odoo 18 的會計模塊&#xff0c;資產的創建和確認可輕松實現自動化。這將使資產管理變得更加簡單高效。使用資產自動化功能&#xff0c;一旦驗證相關產品的供應商賬單&#xff0c;Odoo將自動生成并…

如何輕松地將音樂從 iPhone 傳輸到 Mac?

想把音樂從 iPhone 傳輸到 Mac 嗎&#xff1f;這很常見&#xff0c;無論你是想更換設備、備份收藏&#xff0c;還是只想在更大的屏幕上欣賞喜愛的歌曲。幸運的是&#xff0c;有 6 種有效的方法可以完成這項工作&#xff0c;具體取決于你喜歡使用的工具。讓我們開始吧。 第 1 部…

人工智能——解讀AI智慧課堂系統解決方案【附全文閱讀】

該文檔是 AI 智慧課堂系統解決方案,聚焦教育信息化需求,通過 AI 技術與教學深度融合,解決傳統課堂考勤效率低、資源管理難、分析不精準等問題。 方案以課堂為核心,構建 “背景分析 - 方案設計 - 優勢價值” 框架,技術架構涵蓋教師攝像機、學生抓拍機、智能錄播主機等設備,…

使用Nginx的RTMP模塊進行直播流轉HLS時,處理和預防`.ts`文件過多

當使用Nginx的RTMP模塊進行直播流轉HLS時,如果長時間運行或處理大量流媒體內容,可能會遇到.ts文件累積過多的問題。這不僅會占用大量的磁盤空間,還可能影響系統性能。以下是一些處理和預防.ts文件過多的方法: 1. 配置HLS清理 Nginx RTMP模塊允許配置HLS片段的過期時間,這…

結構體解決冒泡排序

設計英雄的結構體 //1、設計結構體 struct Hero {string name;//姓名int age;//年齡string sex;//性別 };創建英雄的數組 //2、創建數組存放英雄 struct Hero Array[5] {{"劉備", 34 ,"男"},{"關羽", 45 ,"男"},{"張飛",…