C++随机访问文件
C++ Random Access Files
这是我第一次在C++中尝试随机访问文件,但是,我以前在 Java 中尝试过,但我无法让它在C++中工作。这个想法是我想创建 100 条空记录,然后在文件中的特定记录号处存储一条记录。这是我的代码,我尽可能保持简单。
我这里有一个名为工具的结构:
struct Tool {
int number;
char name[20];
int quantity;
double cost;
};
这是我在主函数中拥有的内容:
fstream outFile;
outFile.open("inventory.dat");
// Create 100 empty tool records
Tool tool;
tool.number = 0;
tool.name[0] = ' ';
tool.quantity = 0;
tool.cost = 0;
for (int i = 0; i < 100; i++) {
outFile.write(reinterpret_cast<char *>(&tool.number), sizeof(int));
outFile.write(tool.name, sizeof(char)* 20);
outFile.write(reinterpret_cast<char *>(&tool.quantity), sizeof(int));
outFile.write(reinterpret_cast<char *>(&tool.cost), sizeof(double));
}
// Insert A tool record
Tool t;
t.number = 3;
t.quantity = 7;
t.cost = 57;
strcpy(tool.name, "Electric Sander");
outFile.seekp((tool.number - 1) * sizeof(Tool));
outFile.write(reinterpret_cast<char *>(&tool.number), sizeof(int));
outFile.write(tool.name, sizeof(char)* 20);
outFile.write(reinterpret_cast<char *>(&tool.quantity), sizeof(int));
outFile.write(reinterpret_cast<char *>(&tool.cost), sizeof(double));
outFile.close();
我初始化 100 条空记录的部分工作正常(假设我们要注释代码的插入部分。
但是,当执行插入部分时,我的程序会生成 4 GB 的数据。我不确定发生了什么。我感谢任何形式的帮助。提前谢谢。
你可以写结构的全部内容
outFile.seekp(t.number*sizeof(Tool));
outFile.write(reinterpret_cast<char *>(&tool),sizeof(Tool));
不要忘记告诉编译器不要插入填充
#ifdef MSVC
#pragma pack(push,1)
#endif
struct Tool {
int number;
char name[20];
int quantity;
double cost;
#ifdef GCC
}__attribute__((packed));
#else
};
#endif
#ifdef MSVC
#pragma pack(pop)
#endif
来源:
https://codereview.stackexchange.com/questions/26344/writing-reading-data-structure-to-a-file-using-c
https://stackoverflow.com/a/18654265/194717我们宝贵成员的评论。
你在最后一部分的意思是t
使用了tool
。特别:
outFile.seekp((tool.number - 1) * sizeof(Tool));
应该是:
outFile.seekp((t.number - 1) * sizeof(Tool));
以及末尾的所有其他tool.
字段(假设您要使用 t
)。 此时tool.number
为 0,因此tool.number - 1
为 -1。如果pos_type
是无符号的 32 位,则包装的值将请求的位置置于 4GB 左右。
此外,托马斯·马修斯(Thomas Matthews)在他的评论中提出的对齐点以及托尼(Tony)在他的回答中详细说明的对齐点对于确保文件中的数据正确也很重要。
重复数据删除器和Galik在关于二进制模式的评论中提出的观点对于确保正确写入数据也很重要。
这是一个替代方案:
struct Tool
{
int number;
char name[20];
int quantity;
double cost;
void binary_write(std::ostream& out) const
{
out.write((char *) &number, sizeof(number));
out.write((char *) &name[0], sizeof(name);
out.write((char *) &quantity, sizeof(quantity));
out.write((char *) &cost, sizeof(cost));
}
void binary_read(std::istream& inp)
{
inp.read((char *) &number, sizeof(number));
inp.read((char *) &name[0], sizeof(name);
inp.read((char *) &quantity, sizeof(quantity));
inp.read((char *) &cost, sizeof(cost));
}
size_t binary_size(void) const
{
return sizeof(number) + sizeof(name)
+ sizeof(quantity) + sizeof(cost);
}
};
int main(void)
{
std::ofstream outfile("test.dat", ios::binary);
if (!outfile)
{
cerr << "Error opening test.datn";
return 1;
}
Tool t;
for (unsigned int i = 0; i < 100; ++i)
{
t.binary_write(outfile);
}
outfile.close();
std::ifstream in_file("test.dat", ios::binary)
if (!in_file)
{
cerr << "Error opening test.dat for readingn";
return 2;
}
in_file.seekg(10 * t.binary_size(), ios::beg);
t.binary_read(in_file);
return 0;
}
这里的概念是将读取和写入函数放入对象中,因为对象知道其成员,并且您可以对其他对象隐藏数据(一件好事)。
- 防止临时对象文件访问 MSVC 中的磁盘
- 内存映射文件访问非常慢
- 从多个文件访问静态全局 WinForm UI 对象
- 在单元测试项目中包括 .c 文件,并从多个 cpp 文件访问它而不会出现链接问题
- 如何在Android中从本机编译的c ++二进制文件访问相机
- 如何:监视Windows中另一个进程的文件访问?
- 如何从NTFS中的$ MFT文件访问文件的每个块的文件指针
- 执行C 代码时快速频繁的文件访问
- 使用TDD时隐藏文件访问实现详细信息
- 从C文件访问C 类成员功能
- 从另一个CPP文件访问Form1的文本框,Visual C 2010
- 在所有CPP文件中使用一个Globe变量.如果CPP文件的一个类更改该值,我想从另一个类CPP文件访问它
- 如何从C 文件访问$(target_arch)
- 系统访问出界异常,尝试从flatbuffer的二进制文件访问"LengthofTable"
- 如何声明可通过多个头文件访问的对象
- 使用二进制文件访问违规读取位置
- 哪种类型的文件访问使用
- 在其他源文件中没有通用的头文件访问功能
- 文件访问不起作用
- Windows 8 应用商店应用程序C++文件访问