目录
- 文件
- 文件分类
- 文本文件的读写(ASCII文件)的读写
- 打开文件
- 打开文件的方式
- 关闭文件
- 将数据写入ASCII文件
- 从ASCII文件读入数据
- 二进制存储
- 对比ASCII和二进制存储
- 用成员函数read和write读写二进制文件
- 打开方式
- 文件的读入与读出
文件
- 所谓文件,一般指存储在外部介质上数据的集合。
- 一批数据是以文件的形式存放在外部介质上的
- 操作系统是以文件的形式存放在外部介质上的。
文件分类
- 按存储介质
- 磁盘文件
- 光盘文件
- U盘文件
- 按用途
- 程序文件
- 数据文件
- 按文件中数据的组织形式
- ASCII文件:以ASCII表示的文件,.txt,.cpp
- 二进制文件:用二进制形式表示的文件,可以是.o,.exe等程序文件,也可以是特定格式的数据文件
文件流
- 输出文件流是从内存流向外存文件的数据
- 输入文件流是从外存文件流向内存的数据
- 每一个文件流都有一个内存缓存区与之对应
- 文件流本身不是文件,是以文件为输入输出对象的流
- 要对磁盘文件输入输出,必须通过文件流来实现
- 文件操作需要流对象,cout,cin是已定义的流对象
- 文件操作也要定义流对象,例:ofstream outfile;
文本文件的读写(ASCII文件)的读写
打开文件
- 打开文件是指在文件读写之前做必要的准备工作
(1)为文件流对象和指定的磁盘文件建立关联,以便使文件流流向指定的磁盘文件
(2)指定文件的工作方式
打开文件的两种不同方法
(1)调用文件流的成员函数open,如
ofstream outfile;//定义输出文件流类对象
outfile.open("f1.dat",ios::out);
(2)在定义文件流对象时调用文件流类的构造函数
istream infile("c:\\new\\f1.dat",ios::in);
打开文件的方式
ios::in: 供读,文件不存在时,打开失败(ifstream默认的打开方式)
ios::out:供写,文件不存在则创建,若文件已存在,则清空原内容(ofstream默认的打开方式)
ios::ate:文件打开时,指针在文件最后,可改变指针的位置,常和in,out联合常用
ios::app:供写,文件不存在则创建,若文件已存在,则在原文件内容后添加写入新的内容
ios::trunc:在读写前先将文件长度截断为0(默认)
ios::nocreate:文件不存在时产生错误,常用in或app联合使用
ios::noreplace:文件存在时产生错误,常与out联合使用
ios::binary:二进制格式文件
fstream f("d:\\str\\score.dat",ios::in | ios::out | ios::binary);//以读写方式打开二进制文件
- 打开操作失败,open函数的返回值为0假
if(!outfile.open("fa.dat",ios::app))
{
cerr<<"open error!";
exit(1);
}
关闭文件
- 在对已打开的磁盘文件的读写操作完成后,应关闭该文件。
- 关闭文件,将缓冲区的数据妥善处理,解除了磁盘文件与文件流的关联,不再通过文件流对该文件进行输入或输出
ofstream outfile("f1.dat",ios::out);
outfile.close();
将数据写入ASCII文件
- 读入十个数字
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
int a[10];
for (int i = 0; i < 10; i++)
{
a[i] = i;
}
//打开文件
ofstream ofs("f1.dat", ios::out);
//读入
for (int i = 0; i < 10; i++)
{
ofs << a[i] << ' ';
}
//关闭文件
ofs.close();
return 0;
}
从ASCII文件读入数据
- 读出十个数字
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int a[10];
//打开文件
ifstream ofs("f1.dat", ios::in);
//读出数据
for (int i = 0; i < 10; i++)
{
ofs >> a[i];
}
for (int i = 0; i < 10; i++)
{
cout << a[i] << ' ';
}
//关闭文件
ofs.close();
return 0;
}
- 读入一行字符,把小写字母字符依次存储在磁盘文件f2.dat中。再把它从磁盘文件读出程序,将其中小写字母改为大写字母,再存入磁盘。
#include <iostream>
#include <fstream>
using namespace std;
void save_to_file()
{
ofstream outfile("f2.dat");
char c[80];
cin.getline(c, 80);
for (int i = 0; c[i] != '\0'; i++)
{
if (c[i] >= 'a' && c[i] <= 'z')
{
outfile.put(c[i]);
}
}
outfile.close();
}
void get_from_file()
{
char ch;
ifstream infile("f2.dat");
ofstream outfile("f3.dat");
while (infile.get(ch))
{
outfile.put(ch - 32);
}
infile.close();
outfile.close();
}
int main()
{
save_to_file();
get_from_file();
return 0;
}
二进制存储
- 对于数值数据,ASCII数据与二进制形式不同
- short int类型 12345
用ASCII形式存储
文件打开是长这样的
如果用二进制形式存储
其实就是用两个字节(short int)来存储
而我们打开文件看到的是(有时候会显示出莫名其妙的符号,二进制不是给人看的,是用来存储数据的)
对比ASCII和二进制存储
- ASCII文件直观,便于人阅读,但一般占存储空间较多,且需要花费时间转换;
- 二进制文件是计算机的内部形式,节省空间,且不需要转换,但不能直观显示。
- 对于字符信息,在内存中是以ASCII形式存放,无论是用ASCII文件输出,还是二进制文件输出,形式一样的。
用成员函数read和write读写二进制文件
打开方式
ofstream ofs("file1.dat",ios::out | ios::binary);
ifstream ifs("file2.dat",ios::in | ios::binary);
文件读写方式
istream& read(char *buffer,int len);
ostream& write(const char *buffer,int len);
char *buffer 指向内存中的一段存储空间
int len 是读写的字节数
例如:
ofs.write(p1,50)//将p1指向的空间中50个字节存入文件对象ifs
ifs.read(p2,30)//将文件对象b读出30个字节,存之p2指向空间
文件的读入与读出
#include <iostream>
using namespace std;
#include <fstream>
struct student
{
char name[5];
int num;
int age;
char sex;
};
int main()
{
student stu[3] =
{
{"Li",25,18,'f'},
{"Wang",32,19,'m'},
{"Fun",40,16,'f'}
};
//读到文件里
ofstream outfile("stu.dat", ios::binary);
for (int i = 0; i < 3; i++)
{
outfile.write((char*)&stu[i], sizeof(stu[i]));
}
outfile.close();
//从文件里读入内存
student stu1[3];
ifstream infile("stu.dat", ios::binary);
for (int i = 0; i < 3; i++)
{
infile.read((char*)&stu1[i], sizeof(stu1[i]));
}
infile.close();
for (int i = 0; i < 3; i++)
{
cout << "No." << i + 1 << endl;
cout << "Name:" << stu1[i].name << endl;
cout << "Num:" << stu1[i].num << endl;
cout << "Age:" << stu1[i].age << endl;
cout << "sex:" << stu1[i].sex << endl;
}
return 0;
}