简体   繁体   English

unistd.h 中的 pwrite() 未将数据写入 C++ 中的文件

[英]pwrite() from unistd.h is not writing data to file in C++

Here is my code snippet:这是我的代码片段:

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);
    }

The function seems correct logically. function 在逻辑上似乎是正确的。 But number_of_bytes_written is always -1.但是number_of_bytes_written总是-1。 The file may get created if not exists.如果文件不存在,则可能会创建该文件。 I don't understand why it isn't working.我不明白为什么它不起作用。

Update 1更新 1

Okay, so I got the problem.好的,所以我遇到了问题。 char* buffer is limited by null character. char* buffer受 null 字符的限制。 Hence, the line char *buffer = &bytes_data[0];因此,行char *buffer = &bytes_data[0]; will point to a only a small part of string bytes_data .将指向字符串bytes_data的一小部分。

When I came to know this, I updated that part of my code to当我知道这一点时,我将我的那部分代码更新为

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();
        }

And data() function of std::string doesn't care about null characters according to its C++ reference page as well as this SO post并且根据其 C++ 参考页面以及此 SO 帖子std::stringdata() function 不关心 null 字符

But still, it isn't working out.但是,它仍然没有成功。

If anyone wants to try out the code, I am posting here my sample data to try on.如果有人想尝试代码,我会在此处发布我的示例数据以进行尝试。

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"

Update 2更新 2

I tried writing a string will no null character and still it throws an error.我尝试编写一个字符串将没有 null 字符,但它仍然会引发错误。 Hence, the problem isn't will null character.因此,问题不在于 null 字符。 This seems some memory alignment issue as the disk alignment is already taken care of (I might be wrong because of my limited knowledge in C++).这似乎是一些 memory alignment 问题,因为磁盘 alignment 已经得到处理(由于我对 C++ 的知识有限,我可能错了)。

As, updated in the question at last, the issue wasn't due to null character.正如最后在问题中更新的那样,问题不是由于 null 字符引起的。 Well it was at some point, but the modified code in last edit made sure that null character caused no issues.好吧,它是在某个时候,但上次编辑中的修改代码确保 null 字符没有引起任何问题。

With the help of @IanAbbott, I found out that the issue was with (virtual) memory alignment.在@IanAbbott 的帮助下,我发现问题出在(虚拟)memory alignment 上。 Until then, I always thought that only file offsets are needed to be aligned.在那之前,我一直认为只需要对齐文件偏移量。 But by looking at man page of open() , I found that virtual memory address space also needs to be aligned with SECTOR_SIZE.但是通过查看open()的手册页,我发现虚拟 memory 地址空间也需要与 SECTOR_SIZE 对齐。

By reading a few more articles and documents, I found that mmap is made available for this task.通过阅读更多文章和文档,我发现mmap可用于此任务。 The address returned by mmap (a memory space mapped to file) is always aligned. mmap返回的地址(映射到文件的 memory 空间)总是对齐的。 Hence, finally, I used mmap for doing the task and the code ran without any errors.因此,最后,我使用 mmap 来完成任务,并且代码运行时没有任何错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM