压缩二进制文件
Compressing the binary file
从文件中删除一条记录后,文件中可能有未使用的内存,这些内存曾经被删除的记录占用。文件中许多被删除的记录可能导致文件变得非常大,但实际上只包含很少有用的数据。有两种方法可以避免这种情况:
- 每当在文件中插入一条新记录时,它可以插入到文件中的第一个可用空间中,而不一定是在末尾。但是,如果在文件中搜索第一个可用空间,这可能会导致效率低下——这将使索引结构对该操作的有用性失效。您可以维护一个简单的队列,该队列保存所有已删除记录的locationInFile。无论何时需要插入,都可以从队列中检索(取消队列)元素,并将其用作在文件中存储新记录的位置。(不要忘记更新索引结构)。
- 在达到某个删除阈值后(例如,我们使用5个删除),二进制文件将被压缩。这意味着文件中的所有有效记录将被移动到文件的开头(压缩到开头)。考虑下图,每个方块代表文件中记录的位置,每个整数代表正在使用的有效记录,每个"x"代表已删除的记录:1 × 2 × 3 × 4
文件压缩后,它看起来像这样:1 2 3 4 x x x x
注意,所有有效的记录都被移到了文件的顶部。这种方法需要对索引结构进行重大更新。
**知道如何在代码中实现这个吗?也许seek函数会有用。* *
// This program uses a structure variable to store a record to a file.
#include <iostream>
#include <fstream>
using namespace std;
// Array sizes
const int SSN_SIZE = 10, NAME_SIZE = 51, ADDR_SIZE = 51, PHONE_SIZE = 14;
// Declare a structure for the record.
struct Info {
char ssn[SSN_SIZE];
char name[NAME_SIZE];
int age;
char phone[PHONE_SIZE];
};
int main() {
Info person; // To hold info about a person
char again; // To hold Y or N
// Open a file for binary output.
fstream people("people.dat", ios::out | ios::binary);
do {
// Get data about a person.
cout << "Enter the following data about a " << "person:n";
cout << "SSN: ";
cin.getline(person.ssn, SSN_SIZE);
cout << "Name: ";
cin.getline(person.name, NAME_SIZE);
cout << "Age: ";
cin >> person.age;
cin.ignore(); // Skip over the remaining newline.
cout << "Phone: ";
cin.getline(person.phone, PHONE_SIZE);
// Write the contents of the person structure to the file.
people.write(reinterpret_cast<char *>(&person), sizeof(person));
// Determine whether the user wants to write another record.
cout << "Do you want to enter another record? ";
cin >> again;
cin.ignore(); // Skip over the remaining newline.
} while (again == 'Y' || again == 'y');
// Close the file.
people.close();
people.open("people.dat", ios::in | ios::binary);
if (!people) {
cout << "Error opening file. Program aborting.n";
return 0;
}
cout << "Here are the people in the file:nn";
// Read the first record from the file.
people.read(reinterpret_cast<char *>(&person),
sizeof(person));
// While not at the end of the file, display the records.
while (!people.eof()) {
// Display the record.
cout << "Name: ";
cout << person.name << endl;
cout << "Age: ";
cout << person.age << endl;
cout << "Address line 1: ";
cout << person.address1 << endl;
cout << "Address line 2: ";
cout << person.address2 << endl;
cout << "Phone: ";
cout << person.phone << endl;
// Wait for the user to press the Enter key.
cout << "nPress the Enter key to see the next record.n";
enter code here`cin.get(again);
// Read the next record from the file.
people.read(reinterpret_cast<char *>(&person),
sizeof(person));
}
cout << "That's all the data in the file!n";
people.close();
return 0;
}
你需要考虑的事情太多了…你需要确保在目标位置有足够的空间(没有重叠)…
实际上这是文件系统的功能,所以为什么要重新发明轮子呢?
。在Linux上,您可以在文件中创建文件系统,然后挂载它。然后,您可以为每个人创建一个文件并将其保存在文件系统中。这样,你(几乎)肯定没有错误,并收到安全更新。
如果你不是在Linux上,你可以使用一些文件系统(NTFS, EXT4…)c++ api来直接使用文件系统。
如果你不喜欢这个想法,我建议重新创建整个文件,然后删除旧文件。当然,您只能使用未删除的条目重新创建它。
最后:如果你的文件非常小,那么我认为你实际上根本不需要碎片整理
相关文章:
- 正在读取二进制文件(is_open)
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- Android 在编译二进制文件时重建静态库
- 在 C++ 中将双精度变量写入二进制文件
- clang 的 libFuzzer 可以在同一二进制文件中测试超过 1 个 API 吗?
- C++:实际上不是从二进制文件中读取
- 如何从二进制文件中的给定符号中获取调用程序图
- 将内部带有矢量的结构保存/读取到二进制文件中
- 编译多个C++文件.调用二进制文件以运行代码
- 如何使用位字段将数据从二进制文件复制到结构中?
- uint8_t同一二进制文件的不同十进制值
- C++单个生成文件多个二进制文件
- 尝试将数字写入二进制文件时引发异常
- C++中读/写二进制文件
- 霍夫曼压缩读取文件不会复制二进制文件c++中的所有字节
- 在C++中读取压缩的二进制文件
- 压缩二进制文件