implement libtime on Windows

因為Windows的time命令和Linux的time命令不一樣,嘗試實現libtime

libtime.h

/** libtime.h - 跨平臺時間測量庫* 功能:執行外部命令并測量其運行時間和資源使用*/#ifndef LIBTIME_H
#define LIBTIME_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>#ifdef __cplusplus
extern "C" {
#endif/* 時間測量結果結構體 */
typedef struct {double real_time;   // 實際運行時間(秒)double user_time;   // 用戶CPU時間(秒)double sys_time;    // 系統CPU時間(秒)long   max_rss;     // 最大內存使用(KB)int    exit_status; // 命令退出狀態碼
} libtime_result;/* 輸出格式選項 */
typedef enum {LIBTIME_FORMAT_DEFAULT,  // 默認格式LIBTIME_FORMAT_PORTABLE, // 便攜格式LIBTIME_FORMAT_VERBOSE   // 詳細格式
} libtime_format;/** 執行命令并測量時間* 參數:*   command - 要執行的命令字符串*   result  - 存儲測量結果的結構體指針* 返回值:0=成功,非0=錯誤碼*/
int libtime_execute(const char* command, libtime_result* result);/** 打印測量結果* 參數:*   result - 測量結果*   format - 輸出格式*   stream - 輸出流(stdout/stderr等)*/
void libtime_print(const libtime_result* result, libtime_format format, FILE* stream);/** 解析命令行參數* 參數:*   argc/argv - 命令行參數*   其他參數 - 輸出解析結果* 返回值:0=成功,1=參數錯誤*/
int libtime_parse_args(int argc, char* argv[],libtime_format* out_format,const char** out_output_file,int* out_append,const char** out_custom_format,int* out_cmd_start);/* 釋放動態分配的參數內存 */
void libtime_free_args(char**argv, int count);#ifdef __cplusplus
}
#endif#endif // LIBTIME_H#ifdef LIBTIME_IMPLEMENTATION#include <time.h>
#include <ctype.h>/* 平臺相關實現 */
#if defined(_WIN32) || defined(_WIN64)
#define WIN32_LEAN_AND_MEAN
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif
#include <windows.h>
#include <psapi.h>
#include <shellapi.h>/* Windows時間轉換:FILETIME -> 秒 */
static double filetime_to_sec(const FILETIME* ft) {ULARGE_INTEGER ul;ul.LowPart = ft->dwLowDateTime;ul.HighPart = ft->dwHighDateTime;return (double)ul.QuadPart / 10000000.0; // 100納秒為單位
}#else
/* Linux/macOS 實現 */
#include <unistd.h>
#include <sys/times.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>/* 獲取系統時鐘頻率 */
static long get_clock_ticks() {static long ticks = 0;if (ticks == 0) {ticks = sysconf(_SC_CLK_TCK);}return ticks;
}#endif/* 執行命令并測量時間(核心實現) */
int libtime_execute(const char* command, libtime_result* result) {if (!command || !result) return -1;memset(result, 0, sizeof(libtime_result));#if defined(_WIN32) || defined(_WIN64)/* Windows 實現:通過 cmd.exe 執行命令,支持內置命令和PATH查找 */STARTUPINFOA si = {0};PROCESS_INFORMATION pi = {0};si.cb = sizeof(si);// 讓子進程繼承父進程的標準輸入輸出,確保命令輸出能顯示si.dwFlags = STARTF_USESTDHANDLES;si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);si.hStdError = GetStdHandle(STD_ERROR_HANDLE);// 使用 cmd /c 執行命令,自動處理PATH查找和內置命令char* cmd_line = (char*)malloc(strlen(command) + 8); // 預留 "cmd /c " 空間if (!cmd_line) return -1;sprintf(cmd_line, "cmd /c %s", command);// 高精度計時器LARGE_INTEGER start, end, freq;QueryPerformanceFrequency(&freq);QueryPerformanceCounter(&start);// 創建進程:繼承句柄,不新建窗口BOOL success = CreateProcessA(NULL,               // 不指定程序名,由cmd處理cmd_line,           // 命令行NULL, NULL,         // 安全屬性TRUE,               // 允許句柄繼承(關鍵:確保輸出能顯示)0,                  // 無特殊標志(不新建窗口)NULL, NULL,         // 環境變量和工作目錄&si, &pi);if (!success) {DWORD err = GetLastError();free(cmd_line);return err;}// 等待命令執行完成WaitForSingleObject(pi.hProcess, INFINITE);// 計算實際運行時間QueryPerformanceCounter(&end);result->real_time = (double)(end.QuadPart - start.QuadPart) / freq.QuadPart;// 獲取退出狀態DWORD exit_code;GetExitCodeProcess(pi.hProcess, &exit_code);result->exit_status = exit_code;// 獲取CPU時間FILETIME creation, exit_time, kernel, user;GetProcessTimes(pi.hProcess, &creation, &exit_time, &kernel, &user);result->sys_time = filetime_to_sec(&kernel);result->user_time = filetime_to_sec(&user);// 獲取內存使用PROCESS_MEMORY_COUNTERS_EX pmc;pmc.cb = sizeof(pmc);if (GetProcessMemoryInfo(pi.hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {result->max_rss = pmc.PeakWorkingSetSize / 1024; // 轉換為KB}// 清理資源CloseHandle(pi.hProcess);CloseHandle(pi.hThread);free(cmd_line);return 0;#else/* Linux/macOS 實現:通過 /bin/sh 執行命令 */time_t real_start = time(NULL);pid_t pid = fork();if (pid == -1) {return errno; // fork失敗}if (pid == 0) {// 子進程:執行命令(通過shell處理PATH和內置命令)execl("/bin/sh", "sh", "-c", command, (char*)NULL);exit(EXIT_FAILURE); // execl失敗} else {// 父進程:等待并測量int status;waitpid(pid, &status, 0);result->exit_status = status;result->real_time = difftime(time(NULL), real_start);// 獲取CPU時間和內存使用struct rusage ru;getrusage(RUSAGE_CHILDREN, &ru);result->user_time = (double)ru.ru_utime.tv_sec + ru.ru_utime.tv_usec / 1e6;result->sys_time = (double)ru.ru_stime.tv_sec + ru.ru_stime.tv_usec / 1e6;result->max_rss = ru.ru_maxrss;}return 0;
#endif
}/* 打印測量結果 */
void libtime_print(const libtime_result* result, libtime_format format, FILE* stream) {if (!result || !stream) return;switch (format) {case LIBTIME_FORMAT_PORTABLE:fprintf(stream, "real %f\nuser %f\nsys %f\n",result->real_time, result->user_time, result->sys_time);break;case LIBTIME_FORMAT_VERBOSE:fprintf(stream, "Command exited with status %d\n", result->exit_status);fprintf(stream, "Real time:     %.3f seconds\n", result->real_time);fprintf(stream, "User CPU time: %.3f seconds\n", result->user_time);fprintf(stream, "Sys CPU time:  %.3f seconds\n", result->sys_time);fprintf(stream, "Max RSS:       %ld KB\n", result->max_rss);break;default: // 默認格式fprintf(stream, "\n%.3f real         %.3f user         %.3f sys\n",result->real_time, result->user_time, result->sys_time);break;}
}/* 命令行參數解析輔助函數 */
static void print_help(const char* prog_name, FILE* stream) {fprintf(stream, "Usage: %s [options] command [arguments...]\n", prog_name);fprintf(stream, "Measure the execution time of a command.\n\n");fprintf(stream, "Options:\n");fprintf(stream, "  -p, --portability   Use portable output format\n");fprintf(stream, "  -v, --verbose       Use verbose output format\n");fprintf(stream, "  -o FILE             Write output to FILE\n");fprintf(stream, "  -a                  Append to FILE instead of overwriting\n");fprintf(stream, "  -f FORMAT           Use custom output format\n");fprintf(stream, "  --help              Display this help message\n");fprintf(stream, "  --version           Display version information\n");
}static void print_version(FILE* stream) {fprintf(stream, "libtime 1.0\n");fprintf(stream, "Cross-platform time measurement tool\n");
}/* 解析命令行參數 */
int libtime_parse_args(int argc, char* argv[],libtime_format* out_format,const char** out_output_file,int* out_append,const char** out_custom_format,int* out_cmd_start) {// 初始化默認值*out_format = LIBTIME_FORMAT_DEFAULT;*out_output_file = NULL;*out_append = 0;*out_custom_format = NULL;*out_cmd_start = -1;// 解析參數for (int i = 1; i < argc; i++) {if (strcmp(argv[i], "--help") == 0) {print_help(argv[0], stdout);exit(0);} else if (strcmp(argv[i], "--version") == 0) {print_version(stdout);exit(0);} else if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--portability") == 0) {*out_format = LIBTIME_FORMAT_PORTABLE;} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {*out_format = LIBTIME_FORMAT_VERBOSE;} else if (strcmp(argv[i], "-o") == 0) {if (i + 1 >= argc) {fprintf(stderr, "Error: -o requires a filename argument\n");return 1;}*out_output_file = argv[++i];} else if (strcmp(argv[i], "-a") == 0) {*out_append = 1;} else if (strcmp(argv[i], "-f") == 0) {if (i + 1 >= argc) {fprintf(stderr, "Error: -f requires a format string argument\n");return 1;}*out_custom_format = argv[++i];} else if (argv[i][0] == '-') {fprintf(stderr, "Error: Unknown option '%s'\n", argv[i]);print_help(argv[0], stderr);return 1;} else {// 找到命令起始位置*out_cmd_start = i;break;}}// 檢查是否有命令if (*out_cmd_start == -1) {fprintf(stderr, "Error: No command specified\n");print_help(argv[0], stderr);return 1;}return 0;
}/* 釋放參數內存 */
void libtime_free_args(char**argv, int count) {if (!argv) return;for (int i = 0; i < count; i++) {free(argv[i]);}free(argv);
}#endif // LIBTIME_IMPLEMENTATION

time_cli.c

/** time.c - 跨平臺 time 命令入口程序* 平臺:Windows 使用 WinMain,Linux/macOS 使用 main*/#define LIBTIME_IMPLEMENTATION
#include "libtime.h"#if defined(_WIN32) || defined(_WIN64)
/* Windows 入口:處理寬字符命令行參數 */
#include <windows.h>/* 將寬字符命令行參數轉換為多字節 */
static char** convert_wargv(int argc, wchar_t* wargv[], int* out_argc) {if (!wargv || !out_argc) return NULL;char**argv = (char**)malloc(sizeof(char*) * argc);if (!argv) return NULL;for (int i = 0; i < argc; i++) {// 計算所需緩沖區大小int len = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL);if (len <= 0) {libtime_free_args(argv, i);return NULL;}// 分配并轉換argv[i] = (char*)malloc(len);if (!argv[i]) {libtime_free_args(argv, i);return NULL;}WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,argv[i], len, NULL, NULL);}*out_argc = argc;return argv;
}/* Windows 標準入口函數 */
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd
) {// 獲取寬字符命令行參數int wargc = 0;wchar_t**wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);if (!wargv) {fprintf(stderr, "Error: Failed to parse command line\n");return 1;}// 轉換為多字節參數int argc;char**argv = convert_wargv(wargc, wargv, &argc);LocalFree(wargv); // 釋放寬字符參數if (!argv) {fprintf(stderr, "Error: Failed to convert command line arguments\n");return 1;}#else
/* Linux/macOS 入口:使用標準 main 函數 */
int main(int argc, char* argv[]) {// 直接使用標準C參數,無需轉換
#endif// 解析命令行參數libtime_format format;const char* output_file;int append;const char* custom_format;int cmd_start;if (libtime_parse_args(argc, argv, &format, &output_file, &append, &custom_format, &cmd_start) != 0) {
#if defined(_WIN32) || defined(_WIN64)libtime_free_args(argv, argc);
#endifreturn 1;}// 構建完整命令字符串(拼接命令和參數)size_t cmd_len = 0;for (int i = cmd_start; i < argc; i++) {cmd_len += strlen(argv[i]) + 1; // 加空格}char* command = (char*)malloc(cmd_len + 1);if (!command) {fprintf(stderr, "Error: Out of memory\n");
#if defined(_WIN32) || defined(_WIN64)libtime_free_args(argv, argc);
#endifreturn 1;}command[0] = '\0';for (int i = cmd_start; i < argc; i++) {if (i > cmd_start) strcat(command, " ");strcat(command, argv[i]);}// 執行命令并測量時間libtime_result result;int ret = libtime_execute(command, &result);free(command);if (ret != 0) {fprintf(stderr, "Error: Failed to execute command (error code: %d)\n", ret);
#if defined(_WIN32) || defined(_WIN64)libtime_free_args(argv, argc);
#endifreturn 1;}// 準備輸出流FILE* output = stderr;if (output_file) {output = fopen(output_file, append ? "a" : "w");if (!output) {fprintf(stderr, "Error: Failed to open output file '%s'\n", output_file);
#if defined(_WIN32) || defined(_WIN64)libtime_free_args(argv, argc);
#endifreturn 1;}}// 輸出測量結果if (custom_format) {for (size_t i = 0; i < strlen(custom_format); i++) {if (custom_format[i] == '%' && i + 1 < strlen(custom_format)) {i++;switch (custom_format[i]) {case 'e': fprintf(output, "%.3f", result.real_time); break;case 'U': fprintf(output, "%.3f", result.user_time); break;case 'S': fprintf(output, "%.3f", result.sys_time); break;case 'P': fprintf(output, "%.0f", result.real_time > 0 ? (result.user_time + result.sys_time) / result.real_time * 100 : 0);break;case 'M': fprintf(output, "%ld", result.max_rss); break;case 'x': fprintf(output, "%d", result.exit_status); break;default:  fputc(custom_format[i], output); break;}} else {fputc(custom_format[i], output);}}fprintf(output, "\n");} else {libtime_print(&result, format, output);}// 清理資源if (output_file) fclose(output);
#if defined(_WIN32) || defined(_WIN64)libtime_free_args(argv, argc);
#endifreturn result.exit_status;
}

編譯

  • gcc time_cli.c -lpsapi

測試輸出

timecli.exe -f "=== 執行統計 ===\n實際時間: %e秒\n用戶CPU: %U秒\n系統CPU: %S秒\n內存峰值: %M KB\nCPU使用率: %P\n退出代碼: %x" dirtime.exe python selp.py     
def print_self_source():# __file__ 變量包含當前腳本的路徑with open(__file__, 'r') as f:# 讀取并打印文件內容print(f.read())if __name__ == "__main__":print_self_source()0.104 real         0.016 user         0.000 systime.exe -p ping baidu.comPinging baidu.com [182.61.244.181] with 32 bytes of data:
Reply from 182.61.244.181: bytes=32 time=102ms TTL=49
Reply from 182.61.244.181: bytes=32 time=125ms TTL=49182.61.244.181 的 Ping 統計信息:
^   數據包: 已發送 = 2,已接收 = 2,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒time.exe -v gcc --version
gcc (x86_64-posix-seh-rev0, Built by MinGW-Builds project) 15.1.0
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.Command exited with status 0
Real time:     0.068 seconds
User CPU time: 0.016 seconds
Sys CPU time:  0.016 seconds
Max RSS:       5400 KB

作為庫使用

#define LIBTIME_IMPLEMENTATION
#include "libtime.h"
#include <stdio.h>int main() {libtime_result result;const char* command;// 根據平臺選擇測試命令#ifdef _WIN32command = "dir"; // Windows 命令#elsecommand = "ls -l"; // Linux/macOS 命令#endifprintf("執行命令: %s\n", command);int ret = libtime_execute(command, &result);if (ret != 0) {fprintf(stderr, "命令執行失敗,錯誤碼: %d\n", ret);return 1;}// 打印詳細時間統計printf("\n命令執行統計:\n");libtime_print(&result, LIBTIME_FORMAT_VERBOSE, stdout);return 0;
}

是bug嗎?

  1. 對于阻塞的命令無法計算,比如ping baidu.com無法計算時間
  2. I create shit and bug program, damn

支持的格式符(沒測試)

格式符含義示例輸出
%e實際運行時間(秒,精確到毫秒)1.234
%U用戶CPU時間(秒,精確到毫秒)0.120
%S系統CPU時間(秒,精確到毫秒)0.030
%PCPU使用率(百分比)12%
%M最大內存使用量(KB)1234
%x命令退出狀態碼0
%%輸出百分號本身%

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

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

相關文章

Unity進階--C#補充知識點--【C#各版本的新功能新語法】C#1~4與C#5

來源于唐老獅的視頻教學&#xff0c;僅作記錄和感悟記錄&#xff0c;方便日后復習或者查找 一.C#版本與Unity的關系 1.各Unity版本支持的C#版本 更多信息可以在Untiy官網說明查看 https://docs.unity3d.com/2020.3/Documentation/Manual/CSharpCompiler.html&#xff08;這個好…

水閘安全綜合監測系統解決方案

一、方案概述 水閘作為重要的水利工程設施&#xff0c;承擔著防洪、排澇、供水和灌溉等關鍵功能。其安全性直接關系到下游人民群眾的生命財產安全以及區域經濟的穩定發展。近年來&#xff0c;隨著極端天氣頻發和工程老化問題日益突出&#xff0c;水閘安全監測工作顯得尤為重要。…

基于單片機智能點滴輸液系統

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 該系統基于單片機控制技術&#xff0c;結合傳感器和無線通信模塊&#xff0c;實現對輸液過程的實…

AI數據倉庫管理提升效率

內容概要在數字化轉型浪潮中&#xff0c;AI數據倉庫管理正重塑企業數據處理格局。本部分簡要介紹其核心機制&#xff0c;即通過智能API接入外部數據源實現多平臺數據無縫整合&#xff0c;隨后應用數據清洗技術去除冗余信息&#xff0c;確保數據質量。同時&#xff0c;加密存儲機…

使用 Docker 安裝長安鏈管理平臺 + 部署區塊鏈與示例合約

文章目錄簡介登錄官網GithubPodman 配置&#xff08;Docker 配置 registry 地址&#xff09;安裝長安鏈管理平臺下載源碼docker-compose.yml登錄管理平臺部署區塊鏈Dockerfile構建鏡像部署長安鏈訂閱區塊鏈部署合約下載示例合約部署示例合約投票管理文件哈希存證查找存證信息區…

Python訓練營打卡 DAY 41 簡單CNN

知識回顧 數據增強卷積神經網絡定義的寫法batch歸一化&#xff1a;調整一個批次的分布&#xff0c;常用與圖像數據特征圖&#xff1a;只有卷積操作輸出的才叫特征圖調度器&#xff1a;直接修改基礎學習率 卷積操作常見流程如下&#xff1a; 1. 輸入 → 卷積層 → Batch歸一化層…

云端賦能,智慧運維:分布式光伏電站一體化監控平臺研究

摘要 本文針對分布式光伏電站存在的監管困難、火災隱患、系統繁雜及運維不規范等行業痛點&#xff0c;提出AcrelCloud-1200光伏運維云平臺解決方案。平臺通過ANet-1E2S-4G網關集成多品牌逆變器數據&#xff0c;結合視頻監控與氣象站&#xff0c;實現電站全域監測&#xff1b;開…

CVPR 2025 | 具身智能 | HOLODECK:一句話召喚3D世界,智能體的“元宇宙練功房”來了

關注gongzhonghao【CVPR頂會精選】1.導讀1.1 論文基本信息論文標題&#xff1a;《HOLODECK: Language Guided Generation of 3D Embodied AI Environments》作者&#xff1a;Yue Yang*1, Fan-Yun Sun*2, Luca Weihs*4, Eli Vanderbilt4, Alvaro Herrasti4,Winson Han4, Jiajun …

迅為RK3568開發板搭建Ubuntu環境

本小節介紹開發所需 Ubuntu 環境的搭建方法。系統要求:Ubuntu 系統要求&#xff1a;Ubuntu18.04~21.10 版本。推薦使用 20.04 版本&#xff0c;內存 16GB 及以上&#xff0c;硬盤 100GB 及以上。Ubuntu 系統的用戶名不能包含中文字符。建議 Ubuntu 和 Windows 系統上安裝的 Dev…

【數據結構】用堆解決TOPK問題

設計一個算法&#xff0c;找出數組中最小的k個數。以任意順序返回這k個數均可。示例&#xff1a;輸入&#xff1a; arr [1,3,5,7,2,4,6,8], k 4 輸出&#xff1a; [1,2,3,4]比較替換堆頂的數時&#xff0c;不需要讓堆頂與數組的每一個數再進行比較&#xff0c;比較數組減去k個…

【深度長文】Anthropic發布Prompt Engineering全新指南

目錄 1.什么時候適合用提示工程? 2.如何進行提示工程 2.1 使用提示模板 2.1.1 使用提示模板和變量 2.1.2 何時使用提示模板和變量 2.1.3 提示模板示例 2.2 保持清晰和直接 2.2.1 如何保持清晰、具有上下文和具體 2.2.2 示例 ?2.3 使用示例&#xff08;多示例提示…

【基礎-判斷】HarmonyOS提供了基礎的應用加固安全能力,包括混淆、加密和代碼簽名能力

正確 解釋如下: 應用加固: 這是指對應用程序進行保護,使其更難被逆向工程、篡改或盜版。HarmonyOS 作為現代操作系統,確實提供了這樣的基礎安全能力。 混淆: HarmonyOS 的 SDK 提供了代碼混淆工具(通常基于 ProGuard 或類似技術)。開發者在構建應用時啟用混淆,可以將類…

HTML 框架:構建網頁布局的基石

HTML 框架&#xff1a;構建網頁布局的基石 引言 HTML 框架是網頁設計中不可或缺的一部分&#xff0c;它為網頁內容的布局提供了強大的支持。本文將深入探討 HTML 框架的概念、種類、應用以及如何有效地使用它們來構建網頁布局。 什么是 HTML 框架&#xff1f; HTML 框架是一種網…

[Linux]學習筆記系列 -- [mm][memblock]

文章目錄mm/memblock.c: Linux內核的“拓荒時代”內存管理器一、 核心問題&#xff1a;為什么需要 memblock&#xff1f;二、 核心原理與設計三、 在內核啟動流程中的角色四、 關鍵 API五、 總結include/linux/memblock.hmm/memblock.cmemblock_reserve 預留內存塊for_each_mem…

Java 面試八股文匯總(1000 道附答案解析)

在過 2 個月即將進入金九銀十了&#xff0c;然而面對今年的大環境而言&#xff0c;跳槽成功的難度比往年高了很多&#xff0c;很明顯的感受就是&#xff1a;對于今年的 java 開發朋友跳槽面試&#xff0c;無論一面還是二面&#xff0c;都開始考驗一個 Java 程序員的技術功底和基…

給純小白的Python操作 PDF 筆記

一、文件基礎打開與關閉 推薦用 with open(path, mode, encodingutf-8) as f:&#xff0c;自動完成 close()&#xff0c;避免泄露文件句柄。常見模式&#xff1a;r 讀&#xff0c;w 寫覆蓋&#xff0c;a 追加&#xff0c;rb/wb 二進制。Windows 默認編碼為 GBK&#xff0c;Linu…

vue使用vue-cropper實現圖片裁剪之單圖裁剪

vue制作的pc系統中(如若依系統)&#xff0c;需要實現按照固定尺寸進行裁剪后再進行圖片上傳&#xff0c;以下代碼講述的是實現單張圖片裁剪上傳。1.第一步需要安裝vue-croppernpm install vue-cropper2.第二步在需要的頁面進入代碼引入import {VueCropper} from "vue-crop…

后臺管理系統-5-vue3之子路由渲染首頁及卡片容器和表格容器實現

文章目錄 1 子路由的實現 1.1 router/index.js 1.2 views/Home.vue(首頁) 1.3 Main.vue 2 左上方的卡片 2.1 分欄間隔(Layout布局) 2.2 卡片容器(el-card) 2.3 整體代碼Home.vue 3 左下方的table(靜態實現) 3.1 準備數據 3.2 渲染表格(el-table) 3.3 整體代碼Home.vue 4 附錄 子…

在CentOS系統中查詢已刪除但仍占用磁盤空間的文件

在CentOS系統中查詢已刪除但仍占用磁盤空間的文件在CentOS系統中查詢已刪除但仍占用磁盤空間的文件1. 檢查磁盤整體使用情況2. 查找被刪除但仍被進程占用的文件3. 釋放磁盤空間4. 替代方案&#xff08;不終止進程&#xff09;注意事項補充工具在CentOS系統中查詢已刪除但仍占用…

正點原子【第四期】Linux之驅動開發學習筆記-1.1 Linux驅動開發與裸機開發的區別

前言&#xff1a; 本文是根據嗶哩嗶哩網站上“正點原子【第四期】手把手教你學Linux系列課程之 Linux驅動開發篇”視頻的學習筆記&#xff0c;該課程配套開發板為正點原子alpha/mini Linux開發板。在這里會記錄下正點原子 I.MX6ULL 開發板的配套視頻教程所作的實驗和學習筆記內…