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;支持异步通信、解耦服务、负载均衡和消息缓冲。 核心…