rename系統調用及示例

21. rename - 重命名文件或目錄

函數介紹

rename系統調用用于重命名文件或目錄,也可以將文件或目錄移動到另一個位置。如果目標文件已存在,則會被替換。

函數原型

#include <stdio.h>int rename(const char *oldpath, const char *newpath);

功能

將文件或目錄從舊路徑重命名為新路徑。

參數

  • const char *oldpath: 原文件或目錄的路徑名
  • const char *newpath: 新文件或目錄的路徑名

返回值

  • 成功時返回0
  • 失敗時返回-1,并設置errno:
    • EACCES: 權限不足
    • EBUSY: 文件正被使用
    • EDQUOT: 磁盤配額超限
    • EEXIST: 目標文件存在且不能被替換
    • EINVAL: 參數無效
    • EISDIR: newpath是目錄但oldpath是文件
    • ELOOP: 符號鏈接循環
    • EMLINK: 鏈接數超限
    • ENAMETOOLONG: 路徑名過長
    • ENOENT: 原文件不存在或目標目錄不存在
    • ENOSPC: 磁盤空間不足
    • ENOTDIR: 路徑前綴不是目錄
    • ENOTEMPTY: 目標目錄非空
    • EPERM: 操作不被允許
    • EROFS: 文件系統只讀
    • EXDEV: 跨文件系統移動

相似函數

  • renameat(): 相對路徑版本
  • renameat2(): 增強版本,支持更多選項

示例代碼

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <limits.h>int main() {char buffer[PATH_MAX];char original_dir[PATH_MAX];printf("=== Rename函數示例 ===\n");// 保存原始目錄if (getcwd(original_dir, sizeof(original_dir)) == NULL) {perror("獲取原始目錄失敗");exit(EXIT_FAILURE);}// 示例1: 基本的文件重命名操作printf("\n示例1: 基本的文件重命名操作\n");// 創建測試文件const char *old_filename = "test_rename_old.txt";int fd = open(old_filename, O_CREAT | O_WRONLY, 0644);if (fd == -1) {perror("創建測試文件失敗");exit(EXIT_FAILURE);}const char *file_content = "This is test content for rename function demonstration.";if (write(fd, file_content, strlen(file_content)) == -1) {perror("寫入文件內容失敗");}close(fd);printf("創建測試文件: %s\n", old_filename);// 重命名文件const char *new_filename = "test_rename_new.txt";if (rename(old_filename, new_filename) == -1) {perror("重命名文件失敗");} else {printf("成功將 %s 重命名為 %s\n", old_filename, new_filename);// 驗證文件是否存在if (access(new_filename, F_OK) == 0) {printf("新文件存在\n");// 讀取文件內容驗證fd = open(new_filename, O_RDONLY);if (fd != -1) {char read_buffer[200];ssize_t bytes_read = read(fd, read_buffer, sizeof(read_buffer) - 1);if (bytes_read > 0) {read_buffer[bytes_read] = '\0';printf("文件內容: %s\n", read_buffer);}close(fd);}}if (access(old_filename, F_OK) != 0) {printf("原文件已不存在\n");}}// 示例2: 目錄重命名操作printf("\n示例2: 目錄重命名操作\n");// 創建測試目錄const char *old_dirname = "test_rename_old_dir";const char *new_dirname = "test_rename_new_dir";if (mkdir(old_dirname, 0755) == -1 && errno != EEXIST) {perror("創建測試目錄失敗");} else {printf("創建測試目錄: %s\n", old_dirname);// 在目錄中創建文件char file_in_dir[PATH_MAX];snprintf(file_in_dir, sizeof(file_in_dir), "%s/content.txt", old_dirname);fd = open(file_in_dir, O_CREAT | O_WRONLY, 0644);if (fd != -1) {const char *dir_content = "Content in directory file";write(fd, dir_content, strlen(dir_content));close(fd);printf("在目錄中創建文件: content.txt\n");}// 重命名目錄if (rename(old_dirname, new_dirname) == -1) {perror("重命名目錄失敗");} else {printf("成功將目錄 %s 重命名為 %s\n", old_dirname, new_dirname);// 驗證目錄和內容if (access(new_dirname, F_OK) == 0) {printf("新目錄存在\n");// 檢查目錄中的文件char new_file_path[PATH_MAX];snprintf(new_file_path, sizeof(new_file_path), "%s/content.txt", new_dirname);if (access(new_file_path, F_OK) == 0) {printf("目錄中的文件也已移動\n");}}if (access(old_dirname, F_OK) != 0) {printf("原目錄已不存在\n");}}}// 示例3: 文件移動操作printf("\n示例3: 文件移動操作\n");// 創建另一個目錄用于移動測試const char *move_to_dir = "move_destination";if (mkdir(move_to_dir, 0755) == -1 && errno != EEXIST) {perror("創建目標目錄失敗");} else {printf("創建目標目錄: %s\n", move_to_dir);// 創建要移動的文件const char *file_to_move = "file_to_move.txt";fd = open(file_to_move, O_CREAT | O_WRONLY, 0644);if (fd != -1) {const char *move_content = "This file will be moved to another directory";write(fd, move_content, strlen(move_content));close(fd);printf("創建要移動的文件: %s\n", file_to_move);}// 移動文件到另一個目錄char destination_path[PATH_MAX];snprintf(destination_path, sizeof(destination_path), "%s/%s", move_to_dir, file_to_move);if (rename(file_to_move, destination_path) == -1) {perror("移動文件失敗");} else {printf("成功將文件 %s 移動到 %s\n", file_to_move, destination_path);// 驗證移動結果if (access(destination_path, F_OK) == 0) {printf("文件已在目標位置\n");}if (access(file_to_move, F_OK) != 0) {printf("原位置文件已不存在\n");}}}// 示例4: 替換已存在文件printf("\n示例4: 替換已存在文件\n");// 創建目標文件const char *target_file = "target_file.txt";fd = open(target_file, O_CREAT | O_WRONLY, 0644);if (fd != -1) {const char *target_content = "Original content that will be replaced";write(fd, target_content, strlen(target_content));close(fd);printf("創建目標文件: %s\n", target_file);}// 創建源文件const char *source_file = "source_file.txt";fd = open(source_file, O_CREAT | O_WRONLY, 0644);if (fd != -1) {const char *source_content = "New content that will replace the old content";write(fd, source_content, strlen(source_content));close(fd);printf("創建源文件: %s\n", source_file);}// 讀取替換前的目標文件內容printf("替換前目標文件內容:\n");fd = open(target_file, O_RDONLY);if (fd != -1) {char content_buffer[200];ssize_t bytes_read = read(fd, content_buffer, sizeof(content_buffer) - 1);if (bytes_read > 0) {content_buffer[bytes_read] = '\0';printf("  %s\n", content_buffer);}close(fd);}// 使用rename替換文件if (rename(source_file, target_file) == -1) {perror("替換文件失敗");} else {printf("成功使用 %s 替換 %s\n", source_file, target_file);// 驗證替換結果printf("替換后目標文件內容:\n");fd = open(target_file, O_RDONLY);if (fd != -1) {char content_buffer[200];ssize_t bytes_read = read(fd, content_buffer, sizeof(content_buffer) - 1);if (bytes_read > 0) {content_buffer[bytes_read] = '\0';printf("  %s\n", content_buffer);}close(fd);}// 源文件應該不存在了if (access(source_file, F_OK) != 0) {printf("源文件已被移除\n");}}// 示例5: 錯誤處理演示printf("\n示例5: 錯誤處理演示\n");// 嘗試重命名不存在的文件if (rename("nonexistent_file.txt", "new_name.txt") == -1) {printf("重命名不存在的文件: %s\n", strerror(errno));}// 嘗試重命名到只讀文件系統if (rename(target_file, "/proc/test") == -1) {printf("重命名到只讀文件系統: %s\n", strerror(errno));}// 嘗試使用過長的路徑名char long_path[PATH_MAX + 100];memset(long_path, 'a', sizeof(long_path) - 1);long_path[sizeof(long_path) - 1] = '\0';if (rename(target_file, long_path) == -1) {printf("使用過長路徑名: %s\n", strerror(errno));}// 示例6: 實際應用場景printf("\n示例6: 實際應用場景\n");// 場景1: 日志文件輪轉printf("場景1: 日志文件輪轉\n");const char *log_file = "application.log";const char *old_log_file = "application.log.1";// 創建日志文件fd = open(log_file, O_CREAT | O_WRONLY | O_APPEND, 0644);if (fd != -1) {for (int i = 0; i < 10; i++) {char log_entry[100];sprintf(log_entry, "Log entry %d: Application running normally\n", i);write(fd, log_entry, strlen(log_entry));}close(fd);printf("創建日志文件并寫入測試數據\n");}// 模擬日志輪轉if (access(old_log_file, F_OK) == 0) {unlink(old_log_file);  // 刪除舊的備份}if (rename(log_file, old_log_file) == -1) {perror("日志輪轉失敗");} else {printf("日志文件輪轉成功: %s -> %s\n", log_file, old_log_file);// 創建新的日志文件fd = open(log_file, O_CREAT | O_WRONLY | O_APPEND, 0644);if (fd != -1) {const char *new_log_msg = "New log file created after rotation\n";write(fd, new_log_msg, strlen(new_log_msg));close(fd);printf("創建新的日志文件\n");}}// 場景2: 臨時文件處理printf("場景2: 臨時文件處理\n");const char *temp_file = "temp_processing.tmp";const char *final_file = "final_result.txt";// 創建臨時文件fd = open(temp_file, O_CREAT | O_WRONLY, 0644);if (fd != -1) {const char *temp_content = "Processing result data that needs to be finalized";write(fd, temp_content, strlen(temp_content));close(fd);printf("創建臨時處理文件: %s\n", temp_file);}// 處理完成后重命名為最終文件if (rename(temp_file, final_file) == -1) {perror("重命名臨時文件失敗");} else {printf("臨時文件處理完成: %s -> %s\n", temp_file, final_file);}// 場景3: 原子性文件更新printf("場景3: 原子性文件更新\n");const char *config_file = "config.txt";const char *temp_config = "config.txt.tmp";// 創建原始配置文件fd = open(config_file, O_CREAT | O_WRONLY, 0644);if (fd != -1) {const char *old_config = "old_parameter=value1\nold_setting=enabled\n";write(fd, old_config, strlen(old_config));close(fd);printf("創建原始配置文件\n");}// 創建新的配置文件(臨時)fd = open(temp_config, O_CREAT | O_WRONLY, 0644);if (fd != -1) {const char *new_config = "new_parameter=value2\nnew_setting=disabled\nupdated=true\n";write(fd, new_config, strlen(new_config));close(fd);printf("創建新配置文件(臨時)\n");}// 原子性地替換配置文件if (rename(temp_config, config_file) == -1) {perror("原子性替換配置文件失敗");} else {printf("原子性更新配置文件成功\n");// 驗證新配置printf("更新后的配置文件內容:\n");fd = open(config_file, O_RDONLY);if (fd != -1) {char config_buffer[300];ssize_t bytes_read = read(fd, config_buffer, sizeof(config_buffer) - 1);if (bytes_read > 0) {config_buffer[bytes_read] = '\0';printf("%s", config_buffer);}close(fd);}}// 示例7: 跨文件系統操作限制printf("\n示例7: 跨文件系統操作限制\n");// 這個測試需要實際的跨文件系統環境printf("說明: rename不能跨文件系統移動文件\n");printf("如果嘗試這樣做,會返回EXDEV錯誤\n");printf("跨文件系統移動需要先復制再刪除原文件\n");// 示例8: 性能考慮printf("\n示例8: 性能考慮\n");// rename操作通常是原子性的且很快printf("rename操作的特點:\n");printf("  - 原子性: 操作要么完全成功,要么完全失敗\n");printf("  - 高效性: 通常只是修改元數據,不移動實際數據\n");printf("  - 限制性: 不能跨文件系統操作\n");// 清理測試資源printf("\n清理測試資源...\n");// 刪除各種測試文件和目錄const char *files_to_delete[] = {"test_rename_new.txt","target_file.txt","source_file.txt","file_to_move.txt","application.log","application.log.1","final_result.txt","config.txt"};for (int i = 0; i < 8; i++) {if (access(files_to_delete[i], F_OK) == 0) {if (unlink(files_to_delete[i]) == -1) {printf("刪除文件 %s 失敗: %s\n", files_to_delete[i], strerror(errno));} else {printf("刪除文件: %s\n", files_to_delete[i]);}}}// 刪除目錄if (access("test_rename_new_dir", F_OK) == 0) {char dir_file[PATH_MAX];snprintf(dir_file, sizeof(dir_file), "%s/content.txt", "test_rename_new_dir");unlink(dir_file);if (rmdir("test_rename_new_dir") == -1) {printf("刪除目錄失敗: %s\n", strerror(errno));} else {printf("刪除目錄: test_rename_new_dir\n");}}if (access(move_to_dir, F_OK) == 0) {char moved_file[PATH_MAX];snprintf(moved_file, sizeof(moved_file), "%s/file_to_move.txt", move_to_dir);unlink(moved_file);if (rmdir(move_to_dir) == -1) {printf("刪除目標目錄失敗: %s\n", strerror(errno));} else {printf("刪除目錄: %s\n", move_to_dir);}}return 0;
}

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

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

相關文章

PHP框架之Laravel框架教程:3. 數據庫操作(簡要)

3. 數據庫操作&#xff08;簡要&#xff09; 配置 數據庫的配置文件在 config/database.php 文件中&#xff0c;你可以在這個文件中定義所有的數據庫連接配置&#xff0c;并指定默認的數據庫連接。這個文件中提供了大部分 Laravel 能夠支持的數據庫配置示例。 mysql > [driv…

項目七.AI大模型部署

環境準備此處使用的是rock linux8.9操作系統k8s集群三個設備&#xff0c;使用centos7.9操作系統設備配置##上傳ollama工具的壓縮包 [rootproject ~]# ll total 1497732 -rw-r--r-- 1 root root 1533674176 Jul 21 11:27 ollama-linux-amd64.tgz [rootproject ~]# tar -C /usr -…

Oracle 19C RU 19.28 升級和安裝

背景介紹 概述 本次升級包括安全漏掃中所有19c數據庫,漏掃預警版本19.3到19.27各個版本,數據庫需要升級至19.28版本滿足安全要求。 原端19C 升級目標端19.28 db_name racdb racdb ORACLE_SID racdb1/2 racdb1/2 ORACLE_HOME GI:/oracle/asm DB:/oracle/db GI:/orac…

嵌入式學習日志————對射式紅外傳感器計次

前言這是第二次學習這部分內容了&#xff0c;第一次是大一上學期&#xff0c;因為大二下忙著其他事一直沒來得及吧STM32學完&#xff0c;所以假期從頭開始再學&#xff0c;比第一次也有了更深的理解&#xff0c;以下內容均是看【STM32入門教程-2023版 細致講解 中文字幕】https…

ONLYOFFICE深度解鎖系列.13-如何復制、重新排序 PDF 頁面:onlyoffice 9.0.3 新功能

在處理合同、講義、研究資料或掃描文檔時&#xff0c;保持頁面順序井然尤為重要。有時文件頁數繁多、排序混亂或缺少邏輯&#xff0c;這不僅影響閱讀體驗&#xff0c;也不利于后續使用或分享。好消息是&#xff0c;借助 ONLYOFFICE PDF 編輯器&#xff0c;您可以輕松拖拽頁面&a…

vue遞歸樹形結構刪除不符合數據 生成一個新數組

首先看一下數據結構&#xff08;我的是路由菜單&#xff09;{"code": 200,"message": "請求成功!","success": true,"data": [{"startDate": null,"endDate": null,"createTime": "2023…

【機器學習之推薦算法】基于K最近鄰的協同過濾推薦與基于回歸模型的協同過濾推薦

基于K最近鄰的協同過濾推薦 基于K最近鄰的協同過濾推薦其實本質上就是MemoryBased CF&#xff0c;只不過在選取近鄰的時候&#xff0c;加上K最近鄰的限制。 這里我們直接根據MemoryBased CF的代碼實現 修改以下地方 class CollaborativeFiltering(object):based Nonedef __ini…

望言OCR視頻字幕提取2025終極評測:免費版VS專業版提全方位對比(含免費下載)

大家好&#xff0c;歡迎來到程序視點&#xff01;我是你們的老朋友.小二&#xff01;一、產品定位&#xff1a;AI時代的視頻字幕處理專家望言OCR作為專業的視頻硬字幕提取工具&#xff0c;在AI視頻處理領域占據重要地位。最新評測顯示&#xff0c;其免費版本依然保持著驚人的97…

Matplotlib(二)- Matplotlib簡單繪圖

文章目錄一、pyplot模塊介紹二、Matplotlib簡單繪圖1. 繪制折線圖1.1 折線圖介紹1.2 plt.plot()函數介紹1.3 繪制簡單折線圖1.3.1 繪制單條折線圖1.3.2 繪制多條折線圖1.4 示例&#xff1a;繪制天氣氣溫折線圖2. 繪制柱形圖2.1 柱形圖介紹2.2 plt.bar()函數介紹2.3 繪制柱形圖2…

【世紀龍科技】數字化技術解鎖新能源汽車電驅動總成裝調與檢修

隨著新能源汽車產業加速升級&#xff0c;電驅動總成裝調與檢修技術已成為職業院校汽車專業教學的核心挑戰。傳統實訓模式面臨設備投入高、更新周期長、高壓操作安全隱患多、教學與產業需求脫節等現實問題&#xff0c;導致學生實踐能力培養滯后于行業發展。如何通過數字化手段突…

springboot基于Java與MySQL庫的健身俱樂部管理系統設計與實現

用戶&#xff1a;注冊&#xff0c;登錄&#xff0c;健身教練&#xff0c;健身課程&#xff0c;健身器材&#xff0c;健身資訊&#xff0c;課程報名管理&#xff0c;教練預約管理&#xff0c;會員充值管理&#xff0c;個人中心管理員&#xff1a;登錄&#xff0c;個人中心&#…

如何修改debian的ip地址

編輯配置文件&#xff1a; sudo nano /etc/network/interfaces修改內容&#xff08;示例將 eth0 設為靜態IP&#xff09;&#xff1a; auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 8.8.8.8 8.8.4.4 #…

haproxy七層代理(知識點+相關實驗部署)

目錄 1.負載均衡介紹 1.1 什么是負載均衡 1.2 為什么用負載均衡 1.3 負載均衡類型 1.3.1 四層負載均衡 1.3.2 七層負載均衡 1.3.3 四層和七層的區別 2.haproxy簡介 2.1 haproxy主要特性 2.2 haproxy的優點與缺點 3.haproxy的安裝和服務信息 3.1 實驗環境 3.1.1 hap…

【集合】JDK1.8 HashMap 底層數據結構深度解析

一、核心數據結構&#xff1a;為什么是 "數組 鏈表 紅黑樹"&#xff1f;?HashMap 的底層設計本質是用空間換時間&#xff0c;通過哈希表的快速定位特性&#xff0c;結合鏈表和紅黑樹處理沖突&#xff0c;平衡查詢與插入效率。?1.1 基礎容器&#xff1a;哈希桶數組…

【element-ui】HTML引入本地文件出現font找不到/fonts/element-icons.woff

文章目錄目錄結構問題復現解決辦法目錄結構 |-web|- public|- lib|- ...|- index.htmlindex.html <!DOCTYPE html> <html> <head><meta charset"UTF-8"><!-- import CSS --><link rel"stylesheet" href"./public/…

Windows|CUDA和cuDNN下載和安裝,默認安裝在C盤和不安裝在C盤的兩種方法

本篇文章將詳細介紹在Windows操作系統中配置CUDA和cuDNN的步驟。通過本教程&#xff0c;您將能夠輕松完成CUDA和cuDNN的安裝、環境變量配置以及與深度學習框架&#xff08;如TensorFlow和PyTorch&#xff09;兼容性測試&#xff0c;從而為您的深度學習項目提供強大的硬件支持。…

Vue 項目動態接口獲取翻譯數據實現方案(前端處理語言翻譯 vue-i18n)

在大型多語言項目中&#xff0c;將翻譯數據硬編碼在項目中往往不夠靈活。通過接口動態獲取翻譯數據&#xff0c;并結合本地緩存提升性能&#xff0c;是更優的國際化實現方式。本文將詳細介紹如何在 Vue 項目中實現這一方案。 方案優勢 靈活性高&#xff1a;翻譯內容更新無需修改…

Mybatis-plus多數據源

適用于多種場景&#xff1a;純粹多庫、 讀寫分離、 一主多從、 混合模式等目前我們就來模擬一個純粹多庫的一個場景&#xff0c;其他場景類似場景說明&#xff1a;我們創建兩個庫&#xff0c;分別為&#xff1a; mybatis_plus&#xff08;以前的庫不動&#xff09;與my…

廣東省省考備考(第五十六天7.25)——常識:科技常識(聽課后強化訓練)

錯題解析解析解析解析解析解析解析解析解析標記題解析解析今日題目正確率&#xff1a;40%

RabbitMQ簡述

RabbitMQ簡述 RabbitMQ 是一個開源的 消息代理&#xff08;Message Broker&#xff09; 軟件&#xff0c;實現了 高級消息隊列協議&#xff08;AMQP&#xff09;&#xff0c;用于在分布式系統中存儲、轉發消息&#xff0c;支持異步通信、解耦服務、負載均衡和消息緩沖。 核心…