最近一直在socket,密码大作业,不断提高了对c的要求,也被迫学习一些东西了,以前c的文件操作感觉很是复杂,现在我来总结一下。
1 文件流问题
文件流类与文件流对象
文件流是以外存文件为输入输出对象的数据流。输出文件流是从内存流向外存文件的数据,输入文件流是从外存文件流向内存的数据。每一个文件流都有一个内存缓冲区与之对应。
请区分文件流与文件的概念。文件流本身不是文件,而只是以文件为输入输出对象的流。若要对磁盘文件输入输出,就必须通过文件流来实现。
在C++的I/O类库中定义了几种文件类,专门用于对磁盘文件的输入输出操作除了标准输入输出流类istream,ostream和iostream类外,还有3个用于文件操作的文件类:
(1) ifstream类,它是从istream类派生的。 用来支持从磁盘文件的输入。
(2) ofstream类,它是从ostream类派生的。 用来支持向磁盘文件的输出。
(3) fstream类,它是从iostream类派生的。 用来支持对磁盘文件的输入输出。
要以磁盘文件为对象进行输入输出,必须定义一个文件流类的对象,通过文件流对象将数据从内存输出到磁盘文件,或者通过文件流对象从磁盘文件将数据输入到内存。
其实在用标准设备为对象的输入输出中,也是要定义流对象的,如cin,cout就是流对象,C++是通过流对象进行输入输出的。
由于cin,cout已在iostream.h中事先定义,所以用户不需自己定义。在用磁盘文件时,由于情况各异,无法事先统一定义,必须由用户自己定义。此外,对磁盘文件的操作是通过文件流对象(而不是cin和cout)实现的。文件流对象是用文件流类定义的,而不是用istream和ostream类来定义的。
可以用下面的方法建立一个输出文件流对象:
ofstream outfile;
现在在程序中定义了outfile为ofstream类(输出文件流类)的对象。但是有一个问题还未解决: 在定义cout时已将它和标准输出设备建立关联,而现在虽然建立了一个输出文件流对象,但是还未指定它向哪一个磁盘文件输出,需要在使用时加以指定。
头文件
#include<fstream>
操作
输入流 ifstream 读文件用
输出流 ofstream 写文件用
string s;
ifstream in("1.txt");//定义输入文件流对象,以输入方式打开磁盘文件1.txt
in>>s;
ofstream out("1.txt");
out<<s;
2 fopen操作
//代码实现了将文件按1024字节复制
#include<iostream>
#include<fstream>
using namespace std;
int main ()
{
unsigned char buf[1025];
char b;
int len,r,p;
FILE *fp1,*fp2;
fp1=fopen("1.docx","rb");
fp2=fopen("2.docx","ab");
fseek(fp1,0L,SEEK_END);
len=ftell(fp1);
fseek(fp1,0L,SEEK_SET);
while(len)
{
if(len>=1024)
{
fread(buf,1,1024,fp1); fwrite(buf,1,1024,fp2); len = len - 1024;
}
else{
fread(buf,1,len,fp1); fwrite(buf,1,len,fp2); len = 0;
}
}
/*
r=len/1024;
cout<<len<<endl;
cout<<r;
p=len%1024;
cout<<p;
fseek(fp1,0L,SEEK_SET);
do//注意do while 的使用
{ memset(buf,0,1024);
fread(buf,1,1024,fp1);
if(!r) fwrite(buf,1,p,fp2);
else fwrite(buf,1,1024,fp2);
}while(r--);
*/
/* while(1)//此步实现了单字节复制
{
fread(&b,1,1,fp1);
if(feof(fp1)) break;//注意feof获取的是len+1也就是说只能超界才能返回非零值
fwrite(&b,1,1,fp2);
}*/
//cout<<len;
fclose(fp1);
fclose(fp2);
}
下面一篇会带来socket传送文件的报告