gpt4 book ai didi

c - 为什么 mmap() 会因文件复制程序的目标文件的权限被拒绝而失败?

转载 作者:IT王子 更新时间:2023-10-28 23:59:09 24 4
gpt4 key购买 nike

我想尝试通过 mmap() 在 Linux 中使用内存映射 I/O 将一个文件的内容复制到另一个文件。目的是自己检查这是否比使用 fread()fwrite() 更好,以及它如何处理大文件(例如几个 GiB,因为文件被整个读取我想知道我是否需要为它准备这么大的内存)。

这是我现在正在使用的代码:

// Open original file descriptor:
int orig_fd = open(argv[1], O_RDONLY);
// Check if it was really opened:
if (orig_fd == -1) {
fprintf(stderr, "ERROR: File %s couldn't be opened:\n", argv[1]);
fprintf(stderr, "%d - %s\n", errno, strerror(errno));
exit(EX_NOINPUT);
}
// Idem for the destination file:
int dest_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
// Check if it was really opened:
if (dest_fd == -1) {
fprintf(stderr, "ERROR: File %s couldn't be opened:\n", argv[2]);
fprintf(stderr, "%d - %s\n", errno, strerror(errno));
// Close original file descriptor too:
close(orig_fd);
exit(EX_CANTCREAT);
}

// Acquire file size:
struct stat info = {0};
if (fstat(orig_fd, &info)) {
fprintf(stderr, "ERROR: Couldn't get info on %s:\n", argv[1]);
fprintf(stderr, "%d - %s\n", errno, strerror(errno));
// Close file descriptors:
close(orig_fd);
close(dest_fd);
exit(EX_IOERR);
}
// Set destination file size:
if (ftruncate(dest_fd, info.st_size)) {
fprintf(stderr, "ERROR: Unable to set %s file size:\n", argv[2]);
fprintf(stderr, "%d - %s\n", errno, strerror(errno));
// Close file descriptors:
close(orig_fd);
close(dest_fd);
exit(EX_IOERR);
}

// Map original file and close its descriptor:
char *orig = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, orig_fd, 0);
if (orig == MAP_FAILED) {
fprintf(stderr, "ERROR: Mapping of %s failed:\n", argv[1]);
fprintf(stderr, "%d - %s\n", errno, strerror(errno));
// Close file descriptors:
close(orig_fd);
close(dest_fd);
exit(EX_IOERR);
}
close(orig_fd);
// Map destination file and close its descriptor:
char *dest = mmap(NULL, info.st_size, PROT_WRITE, MAP_SHARED, dest_fd, 0);
if (dest == MAP_FAILED) {
fprintf(stderr, "ERROR: Mapping of %s failed:\n", argv[2]);
fprintf(stderr, "%d - %s\n", errno, strerror(errno));
// Close file descriptors and unmap first file:
munmap(orig, info.st_size);
close(dest_fd);
exit(EX_IOERR);
}
close(dest_fd);

// Copy file contents:
int i = info.st_size;
char *read_ptr = orig, *write_ptr = dest;
while (--i) {
*write_ptr++ = *read_ptr++;
}

// Unmap files:
munmap(orig, info.st_size);
munmap(dest, info.st_size);

我认为这可能是一种方法,但我在尝试映射目标文件时不断收到错误消息,具体是代码 13(权限被拒绝)。

我不知道为什么会失败,我可以写入该文件,因为该文件已创建,而且我要复制的所有文件大小只有几个 KiB。

有人能发现问题吗?为什么我有权映射原始文件而不是目标文件?

注意:如果有人要使用循环来复制问题中发布的字节而不是 memcpy,例如,循环条件应该是 i-- 而不是复制所有内容。感谢 jxh 发现这一点。

最佳答案

来自 mmap() 手册页:

EACCES
A file descriptor refers to a non-regular file. Or MAP_PRIVATE was requested, but fd is not open for reading. Or MAP_SHARED was requested and PROT_WRITE is set, but fd is not open in read/write (O_RDWR) mode. Or PROT_WRITE is set, but the file is append-only.

您正在使用 O_WRONLY 打开目标文件。请改用 O_RDWR

此外,您应该使用memcpy 来复制内存而不是使用您自己的循环:

memcpy(dest, orig, info.st_size);

您的循环有 1 个错误。

关于c - 为什么 mmap() 会因文件复制程序的目标文件的权限被拒绝而失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17202741/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com