因此,我被要求将一些代码从C“翻译”到C++,真正的要求是尽可能地删除原始C,并用C++ STL函数调用替换它。
我必须更改的一件事是将pwrite
和pread
的用法分别更改为std::fwrite
和std::fread
,但是,当前代码大量使用pwrite
和pread
的偏移选项,因为数据将被写入Linux或BSD系统上的设备,即/dev/sda1
。
但是std::fwrite
和std::fread
没有像pwrite
和pread
那样的偏移量参数,所以根据我的理解,我需要先使用std::fseek
查找文件中的偏移量,然后再执行写/读操作,我的理解是否正确?
我已经写了一个小的测试程序来验证我的假设,见下文,但我想在启动代码之前更确定一点。
测试程序如下所示:clang++ -std=c++17 main.cpp
#include <vector>
#include <string>
#include <ctime>
#include <algorithm>
#include <cstdio>
void write(const std::string& device, const size_t offset, const std::vector<uint8_t>& data)
{
std::FILE* fp = std::fopen(device.c_str(), "wb");
if (offset != 0)
{
std::fseek(fp, 0, offset);
}
std::fwrite(data.data(), sizeof(uint8_t), data.size(), fp);
std::fclose(fp);
}
std::vector<uint8_t> read(const std::string& device, size_t offset, const size_t size)
{
std::vector<uint8_t> data(size);
std::FILE* fp = std::fopen(device.c_str(), "rb");
if (offset != 0)
{
std::fseek(fp, 0, offset);
}
std::fread(data.data(), sizeof(uint8_t), size, fp);
std::fclose(fp);
return data;
}
std::vector<std::vector<uint8_t>> generate(const size_t num_vec, const size_t data_size)
{
std::vector<std::vector<uint8_t>> vectors;
for (size_t i = 0; i < num_vec; ++i)
{
std::vector<uint8_t> data(data_size);
std::generate(data.begin(), data.end(), rand);
vectors.push_back(data);
}
return vectors;
}
int main(void)
{
srand(static_cast<uint32_t>(time(0)));
const std::string device = "/dev/sda1";
const size_t size = 4096;
const size_t num_vec = 4;
auto vectors = generate(num_vec, size);
size_t offset = 0;
for (const auto& vec : vectors)
{
write(device, offset, vec);
auto other = read(device, offset, size);
if (vec != other)
{
std::puts("success");
}
else
{
std::puts("failure");
}
offset = offset + size;
}
}
2条答案
按热度按时间xj3cbfub1#
您交换了一些参数。
fseek
调用应如下所示否则你的理解是正确的。先查找,然后读取。注意,这个两步解决方案a)较慢(两次系统调用),B)如果在多个线程中使用相同的
FILE*
,则不安全。既然您提到了转换为C++:
fwrite
和fseek
是C库的一部分。如果您需要STL C++解决方案,请切换到std::fstream
。guykilcj2#
您的理解是正确的,但参数是错误的。要从文件开头查找第
n
个字节,请使用:根据功能描述:
如果流以二进制模式打开,则新位置正好是从文件开头(如果源是SEEK_SET)、从当前文件位置(如果源是SEEK_CUR)和从文件结尾(如果源是SEEK_END)测量的偏移字节。二进制流不需要支持SEEK_END,特别是在输出其他空字节时。
See example at the bottom of a cppreference page.