[英]pwrite() from unistd.h is not writing data to file in C++
这是我的代码片段:
void
DirectIO::writeFileUnix(const std::string &file_path,
unsigned long long int index,
size_t size,
std::string &bytes_data) {
WRITE_COUNT++;
const int file_descriptor = open(file_path.c_str(),
O_WRONLY | O_DIRECT | O_SYNC | O_CREAT, S_IRUSR | S_IWUSR);
if (file_descriptor == -1 || size % SECTOR_SIZE != 0) {
throw std::exception();
}
char *buffer = &bytes_data[0];
ssize_t number_of_bytes_written = pwrite(file_descriptor, buffer, size, index * size);
if (number_of_bytes_written == -1 || number_of_bytes_written < size) {
throw std::exception();
}
close(file_descriptor);
}
function 在逻辑上似乎是正确的。 但是number_of_bytes_written
总是-1。 如果文件不存在,则可能会创建该文件。 我不明白为什么它不起作用。
好的,所以我遇到了问题。 char* buffer
受 null 字符的限制。 因此,行char *buffer = &bytes_data[0];
将指向字符串bytes_data
的一小部分。
当我知道这一点时,我将我的那部分代码更新为
void *buffer = bytes_data.data();
ssize_t number_of_bytes_written = pwrite(file_descriptor, buffer, size, index * size);
if (number_of_bytes_written == -1 || number_of_bytes_written < size) {
throw std::exception();
}
并且根据其 C++ 参考页面以及此 SO 帖子, std::string
的data()
function 不关心 null 字符
但是,它仍然没有成功。
如果有人想尝试代码,我会在此处发布我的示例数据以进行尝试。
bytes_data - "\000\000\000\000\005\000\000\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000....\000" (octal representation as supported by clion)
index = 0
size = 4096 (length of bytes_data)
file_path = "abc.binary"
我尝试编写一个字符串将没有 null 字符,但它仍然会引发错误。 因此,问题不在于 null 字符。 这似乎是一些 memory alignment 问题,因为磁盘 alignment 已经得到处理(由于我对 C++ 的知识有限,我可能错了)。
正如最后在问题中更新的那样,问题不是由于 null 字符引起的。 好吧,它是在某个时候,但上次编辑中的修改代码确保 null 字符没有引起任何问题。
在@IanAbbott 的帮助下,我发现问题出在(虚拟)memory alignment 上。 在那之前,我一直认为只需要对齐文件偏移量。 但是通过查看open()
的手册页,我发现虚拟 memory 地址空间也需要与 SECTOR_SIZE 对齐。
通过阅读更多文章和文档,我发现mmap
可用于此任务。 mmap
返回的地址(映射到文件的 memory 空间)总是对齐的。 因此,最后,我使用 mmap 来完成任务,并且代码运行时没有任何错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.