可以将顺序文件看作一个有限字符构成的顺序字符流,然后像对cin,cout一样的读写。回顾下输入输出流的层次结构。
目录
创建文件
#include<fstream> //包含头文件
方式1:
定义ofstream,在构造函数中给出参数
ofstream outFile(“clients.dat”,ios::out|ios::binary); -clients..dat 要创建的文件的名字 -ios::out 文件打开方式 ios::out 输出到文件,删除原有内容 ios::app 输出到文件,保留原有内容,总是在尾部添加(app - append) -ios::binary 以二进制方式打开文件
方式2:
创建ofstream对象,再用open函数打开
ofstream fout; //创建ofstream对象
fout.open(“test.out”,ios::out|ios::binary);
判断打开是否成功
if(!fout){ cout«“File open error!”«endl;
}
文件名可以给出绝对路径,也可以给出相对路径。没有交代路径信息,就是在当前文件夹下寻找。
-
绝对路径
e.g. “c:\tmp\mydir\some.txt”
-
相对路径
- “\tmp\mydir\some.txt”
当前盘符的根目录下的tmp\dir\some.txt
-
“tmp\mydir\some.txt”
当前文件夹的tmp子文件夹里面的…
-
“..\ tmp\mydir\some.txt”
当前文件夹的父文件夹下面的tmp子文件夹里面的…
-
“..\..\ tmp\mydir\some.txt”
当前文件夹的父文件夹的父文件夹下面的tmp子文件夹里面的…
文件的读写指针
对于输入文件,有一个读指针;对于输出文件,有一个写指针;对于输入输出文件,有一个读写指针;指针的作用即为,标识文件操作的当前位置,该指针在哪里,读写操作就在哪里进行。
写操作
tellp()取得写指针位置 seekp(location)向指定位置写入
ofstream fout(“a1.out”,ios::app); //以添加方式打开
long location = fout.tellp(); //取得写指针的位置
location p = 10;
fout.seekp(location); //将写指针移动到底10个字节处
fout.seekp(location, ios::beg); //从头部数location个字节 (beg-begin)
fout.seekp(location, ios::cur); //从当前位置数location个字节 (cur-current)
fout.seekp(location, ios::end); //从尾部数location个字节 (这种情况下location<=0)
读操作
tellg()取得读指针位置 seekg(location)从指定位置读
ifstream fin(“a1.in”,ios::ate); //打开文件,定位文件指针到文件尾(ate-at end)
long location = fin.tellg(); //获取读指针的位置,从而可以获取文件长度
location = 10;
fin.seekg(location); //将头指针移动到低10个字节处
fin.seekg(location, ios::beg); //从头部数location个字节
fin.seekg(location, ios::cur); //从当前位置数location个字节
fin.seekg(location, ios::end); //从尾部数location个字节
显示关闭文件
ifstream fin(“test.dat”, ios::in);
fin.close();
ofstream fout(“test.dat”, ios::out);
fout.close();
文件读写
字符文件读写
因为文件也是流,所以流的成员函数和流操作算子也同样适用于文件流。
e.g. 1.写一个程序,将文件in.txt里面的整数排顺后,输出到out.txt
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int> v;
ifstream srcFile("in.txt",ios::in);
ofstream destFile("out.txt",ios::out);
int x;
while (srcFile >> x)
v.push_back(x);
sort(v.begin(),v.end());
for(int i = 0; i < v.size(); i++)
destFile<<v[i]<<" ";
destFile.close();
srcFile.close();
return 0;
}
运行结果:
二进制文件读写
从文件读入内存
ifstream和fstream的成员函数:
istream& read (char* s, long n);
将文件读指针指向的地方的n个字节的内容,读入到内存地址s,然后将文件读指针向后移动n字节。
从内存写入文件
ofstream和fstream的成员函数:
istream& write(const char* s, long n);
将内存地址s处的n个字节内容,写入到文件中写指针指向的位置,然后将文件写指针向后移动n字节。
e.g. 1.从键盘输入几个学生的姓名的成绩,并以二进制文件形式保存
#include<iostream>
#include<fstream>
using namespace std;
struct Student{
char name[20];
int score;
};
int main()
{
Student s;
ofstream OutFile("students.dat",ios::out|ios::binary);
while(cin>>s.name>>s.score)
OutFile.write((char *) & s, sizeof(s) );
//(char *) & s表示取s的地址,并转为char*类型
OutFile.close();
return 0;
}
输入:
Tom 60
Jack 80
Peter 100
^Z + 回车
运行结果:
当前文件夹下生产student.dat文件,且为72字节(20B+4B)* 3 = 72B
使用记事本打开,呈现:
使用sublime text3打开,呈现:
会发现其以二进制形式存储, \(3C_{16}\)对应分数\(60_{10}\), \(50_{16}\)对应分数\(80_{10}\), \(64_{16}\)对应分数\(100_{10}\).
还可以发现,这里是以大端模式进行存储的。(即数据的高字节,在内存的低地址;数据的低字节,在内存的高地址)
e.g. 2.将student.dat文件的内容读出并显示出来.
#include<iostream>
#include<fstream>
using namespace std;
struct Student{
char name[20];
int score;
};
int main()
{
Student s;
ifstream inFile("students.dat",ios::in|ios::binary);
if(!inFile){
cout<<"Error."<<endl;
return 0;
}
while(inFile.read((char* ) &s, sizeof(s) )){
cout<<s.name<<" "<<s.score<<endl;
}
inFile.close();
return 0;
}
运行结果:
转载请注明原地址,小黑特的博客:http://te-shi.com 谢谢!