当前位置: 首页 > news >正文

Linux_fileio实现copy文件

参考韦东山老师教程:https://www.bilibili.com/video/BV1kk4y117Tu?p=12

目录

    • 1. 通过read方式copy文件
    • 2. 通过mmap映射方式copy文件

1. 通过read方式copy文件

copy文件代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>/** ./copy 1.txt 2.txt* argc    = 3* argv[0] = "./copy"* argv[1] = "1.txt"* argv[2] = "2.txt"*/
int main(int argc, char **argv)
{int fd_old, fd_new;char buf[1024];int len;/* 1. 判断参数 */if (argc != 3) {printf("Usage: %s <old-file> <new-file>\n", argv[0]);return -1;}/* 2. 打开老文件 */fd_old = open(argv[1], O_RDONLY);if (fd_old == -1){printf("can not open file %s\n", argv[1]);return -1;}/* 3. 创建新文件 */fd_new = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);if (fd_new == -1){printf("can not creat file %s\n", argv[2]);return -1;}/* 4. 循环: 读老文件-写新文件 */while ((len = read(fd_old, buf, 1024)) > 0){if (write(fd_new, buf, len) != len){printf("can not write %s\n", argv[2]);return -1;}}/* 5. 关闭文件 */close(fd_old);close(fd_new);return 0;
}

上传到Ubuntu后编译运行:

在这里插入图片描述

2. 通过mmap映射方式copy文件

mmap映射方式copy文件代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>/** ./copy 1.txt 2.txt* argc    = 3* argv[0] = "./copy"* argv[1] = "1.txt"* argv[2] = "2.txt"*/
int main(int argc, char **argv)
{int fd_old, fd_new;struct stat stat;char *buf;/* 1. 判断参数 */if (argc != 3) {printf("Usage: %s <old-file> <new-file>\n", argv[0]);return -1;}/* 2. 打开老文件 */fd_old = open(argv[1], O_RDONLY);if (fd_old == -1){printf("can not open file %s\n", argv[1]);return -1;}/* 3. 确定老文件的大小 */if (fstat(fd_old, &stat) == -1){printf("can not get stat of file %s\n", argv[1]);return -1;}/* 4. 映射老文件 */buf = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd_old, 0);if (buf == MAP_FAILED){printf("can not mmap file %s\n", argv[1]);return -1;}/* 5. 创建新文件 */fd_new = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);if (fd_new == -1){printf("can not creat file %s\n", argv[2]);return -1;}/* 6. 写新文件 */if (write(fd_new, buf, stat.st_size) != stat.st_size){printf("can not write %s\n", argv[2]);return -1;}/* 5. 关闭文件 */close(fd_old);close(fd_new);return 0;
}

上传到Ubuntu后编译运行:

在这里插入图片描述

fstat函数使用方法:

fstat函数用于获取一个已经打开的文件的状态信息。它通常在编程语言中用于文件操作。

函数原型参数返回值
#include <sys/stat.h>
int fstat(int filedes, struct stat *buf);
filedes:这是文件描述符,通常通过open或fileno函数获得。
buf:是一个指向struct stat结构体的指针,用于存放文件的状态信息。
struct stat结构体包含了文件的各种信息,例如:

st_dev:设备ID。
st_ino:inode号。
st_mode:文件类型和权限位。
st_nlink:硬链接数量。
st_uid:文件拥有者的用户ID。
st_gid:文件拥有者的组ID。
st_rdev:如果是设备文件,则包含设备ID。
st_size:文件大小,以字节为单位。
st_atime、st_mtime、st_ctime:分别是最后一次访问、修改和状态变化的时间。
调用成功返回0,调用失败返回-1,并且会设置全局变量errno来表示具体的错误原因

在这里插入图片描述

在这里插入图片描述

mmap函数使用方法:

mmap函数是Unix和类Unix操作系统(包括Linux)中用于内存映射文件或设备的一种系统调用。它允许应用程序将一个文件或者其它对象映射到进程的地址空间,使得对这段内存区域的访问就像访问一个普通数组一样简单,同时又保留了文件的持久性。

函数原型参数返回值
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);addr:期望映射到的起始地址,通常设置为NULL以让系统选择一个合适的地址。
length:映射的字节数。
prot:指定映射区域的保护标志,可以是以下值的组合:
PROT_READ:映射区域可读。
PROT_WRITE:映射区域可写。
PROT_EXEC:映射区域可执行。
PROT_NONE:映射区域不可访问。
flags:映射的类型和特性标志,常见标志包括:
MAP_SHARED:多个进程可以共享映射区域,对映射区域的写操作会被写回原文件。
MAP_PRIVATE:创建私有副本,写操作不会影响原文件,会产生一份副本(写时复制)。
MAP_FIXED:强制映射到addr指定的地址,如果该地址已被使用,则会触发SIGBUS信号。
MAP_ANONYMOUS 或 MAP_ANON:映射匿名内存,不与任何文件关联。
fd:文件描述符,指定要映射的文件或设备。
offset:文件中的起始偏移量,单位是字节。
mmap成功时返回映射区域的起始地址,失败时返回MAP_FAILED(通常被定义为(void *) -1),此时可以通过errno变量检查具体的错误原因。

在这里插入图片描述

在这里插入图片描述

相关文章:

  • RK3568平台(USB篇)USB HID设备
  • 【文件上传】
  • Linux CentOS 环境 MySQL 主从复制集群搭建
  • 电信NR零流量小区处理
  • java 操作 milvus 2.1.4
  • 税务笔记()
  • 性能调优 性能监控
  • Hadoop3:Yarn框架的三种调度算法
  • SUPERVIVE无法联机、联机失败、联机报错的解决办法分享
  • AI与音乐:终极对决,机械混音师将扬弃人类知识!
  • Webpack: 开发 PWA、Node、Electron 应用
  • C语言笔记27 •单链表介绍•
  • Yolov8可视化界面使用说明,含代码
  • FastAPI 基本路由
  • 新能源行业知识体系-------主目录-----持续更新
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Angular数据绑定机制
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • create-react-app项目添加less配置
  • gitlab-ci配置详解(一)
  • Hexo+码云+git快速搭建免费的静态Blog
  • JavaScript设计模式系列一:工厂模式
  • k8s如何管理Pod
  • MaxCompute访问TableStore(OTS) 数据
  • python学习笔记 - ThreadLocal
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • 基于Android乐音识别(2)
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 记一次和乔布斯合作最难忘的经历
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 每天一个设计模式之命令模式
  • 强力优化Rancher k8s中国区的使用体验
  • 推荐一个React的管理后台框架
  • 小李飞刀:SQL题目刷起来!
  • 一天一个设计模式之JS实现——适配器模式
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​io --- 处理流的核心工具​
  • ​水经微图Web1.5.0版即将上线
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)计算机毕业设计ssm电影分享网站
  • (已解决)什么是vue导航守卫
  • .form文件_SSM框架文件上传篇
  • .gitignore文件忽略的内容不生效问题解决
  • .NET 8.0 中有哪些新的变化?
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .Net各种迷惑命名解释
  • :如何用SQL脚本保存存储过程返回的结果集
  • @Repository 注解
  • @RequestBody与@ModelAttribute
  • [ C++ ] STL---stack与queue
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择