我正在寻找完成标题中指定内容的最佳方法。假设我有一个文件(为了简单起见,让它成为一个文本文件),带有一个预先排序的数字列表,例如
0 2 3 4 4 6 12 13 14 16 16 16 17 18 ...
我想在此列表中插入一个新数字,假设 5 ,而不是将所有内容都加载到内存中并再次对文件中的每个项目执行排序(这只是一个示例,在我的case我有大量的数据并将所有内容加载到内存中是不可行的)并且不将文件拆分为“下限”和“上限”部分(临时文件)以使用中间的数字重新加入它们。 是否有任何方法可以在文件的给定位置插入一些东西,并使该偏移量只需“移位”以获得适当的字节数?
欢迎使用标准功能的解决方案,例如(f)open,(f)write等,以及Windows特定的API(内存映射文件)。
答案 0 :(得分:1)
根据文件系统和操作系统的实现方式,我会说这个问题的解决方案是不可能的。
我建议你需要一个SQL数据库......
如果你在谈论排序的二进制记录,其中记录的大小与磁盘上扇区的大小完全匹配,理论上可以避免在文件元数据以外的磁盘上重写数据,如果你有一个假设的文件系统允许您将“扇区”插入文件的中间。
理论上,无论如何,好像存在这样的strange file system(向下滚动到'REL'文件类型 - 从未想过我会再考虑这个问题!)......
答案 1 :(得分:-1)
这是你不想要的解决方案,没有使用SQL你想要什么是不可能的..但这里是临时文件的方式....
它将所有内容加载到内存中并执行一些处理,然后再将所有项目写回文件。
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
using namespace std;
void displaystudentdata()
{
string name, grade, tname;
int age, x=0; // x - "counter" to check if user entered wrong name
system("cls");
ifstream students("students.txt");
cout<<"-------------------------------------------------------------------\n\n";
while(students >> name >> grade >> age)
{
cout<<"Name= "<<name <<", Grade= "<< grade <<" , Age= " <<age<<"\n";
}
students.clear(); // clear eof and fail bits
students.seekg(0, ios::beg);
students.close();
}
void deletestudentdata()
{
string name, grade, tname;
int age, x=0; // x - "counter" to check if user entered wrong name
ifstream students("students.txt");
ofstream temp("temp.txt"); // temp file for input of every student except the one user wants to delete
cout<<"-------------------------------------------------------------------\n\n";
cout << "Enter name of the student you want to erase from database >" << endl;
cin >> tname;
//ifstream students("students.txt");
//ofstream temp("temp.txt"); // temp file for input of every student except the one user wants to delete
while(students >> name >> grade >> age)
{
if(tname!=name){ // if there are students with different name, input their data into temp file
temp << name << ' ' << grade << ' ' << age << endl;
}
if(tname==name){ // if user entered correct name, x=1 for later output message that the user data has been deleted
x=1;
}
}
students.clear(); // clear eof and fail bits
students.seekg(0, ios::beg);
students.close();
temp.close();
remove("students.txt");
rename("temp.txt","students.txt");
if(x==0){ // x was set to 0 at start, so if it didn't change, it means user entered the wrong name
cout << "There is no student with name you entered." << endl;
}
else{ // x is not 0, it means user entered the correct name, print message that students data has been deleted
cout << "Student data has been deleted." << endl;
}
}
int main(void)
{
displaystudentdata();
deletestudentdata();
displaystudentdata();
cout << "Student data has been deleted. \n\n" << endl;
cout<<" \nPress any key to continue\n";
cin.ignore();
cin.get();
return 0;
}