您的位置:首页 > 财经 > 产业 > Linux_fileio实现copy文件

Linux_fileio实现copy文件

2024/12/23 5:04:56 来源:https://blog.csdn.net/studyingdda/article/details/140137975  浏览:    关键词: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变量检查具体的错误原因。

在这里插入图片描述

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com