C++文件操作:fstream 文件流对象,写入的时候数据就在文件中。
C文件操作:都是用函数来实现的,用FILE*fp的指针来对应文件,如果没有调用fclose关闭保存文件,数据不在文件中。
fprintf:站在文件的角度是写入,站在内存的角度是输出
fscanf:站在文件的角度是读取,站在内存的角度是输入
#include <iostream>
#include <fstream>
#include <iostream>
#include <string>
using std::string;
using std::fstream;
using std::cout;
using std::endl;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
//1.创建文件流对象
fstream file;
//2.打开文件:文件流对象关联文件 对应C语言中的文件指针关联文件
file.open("newer.txt",std::ios::out);//file.open(带路径的文件名,in和out是相对于内存而言的)写入到文件里面去out,读取文件是in
//3.写入数据到文件中
file<<"同学们好"<<endl;
file<<"今天强哥有点感冒,请见谅"<<endl;
//4.关闭文件
file.close();
//5.读取方式打开文件
file.open("newer.txt",std::ios::in);
//6把数据从文件中读取到内存中
string buff;//内存中
file>>buff;
cout<<"从文件中读到了:" ;
cout<<buff<<endl;
file>>buff;
cout<<"从文件中读到了:" ;
cout<<buff<<endl;
file.close();
return 0;
}
字符流:由很多字符组成。需要经过ASCII码转换。r r+ w w+ a a+ std::ios::in std::ios::out
.txt .c .cpp
字节流:由字节组成。不需要经过ASCII码的转换。rb r+b wb w+b ab a+b std::ios::in| std::ios::binary(死记硬背住)
.exe .obj. jpg .png .avi .mp3 .mp4 .mv
拷贝文件函数
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
//源文件 目的文件
fstream srcFile,dstFile;
//string buff;
char c;
srcFile.open("CPPDay07.cpp",std::ios::in);//读字符流的方式打开源文件
dstFile.open("2.txt",std::ios::out);//写字符流的方式打开目的文件
while(1){
//源文件中读取数据到buff中
//srcFile.read(buff,1024);//(读了放到什么地方,一次读多少)
c=srcFile.get();//一个字符一个字符读
//源文件中读取不到数据了,结束
if(c==EOF) break;//define EOF -1 代表文件结束
//把buff中数据写入到目的文件中
printf("%c",c);
dstFile.put(c);
}
srcFile.close();
dstFile.close();
return 0;
}
拷贝字节类型的文件(字符类型文件用字节流没有问题,但是如果是字节类型的文件你用字符流,那么就会有问题。)
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
//源文件 目的文件
fstream srcFile,dstFile;
//string buff;
char c;
srcFile.open("6.jpg",std::ios::in|ios::binary);//读字符流的方式打开源文件
dstFile.open("9.jpg",std::ios::out|ios::binary);//写字符流的方式打开目的文件
//获取srcFile大小
//1设置文件内容指针指向文件末尾
srcFile.seekg(0,ios::end);//使用seekg,seekp无所谓,下面用tell的时候对应即可 (距离文件末尾0字节)
//2获取文件内容指针到文件头字节数
std::streamoff size=srcFile.tellg();
//3文件内容指针还原到文件头 ,如果不还原到文件头,之后用的get函数就会从文件尾开始读。
srcFile.seekg(ios::beg);
for(size_t i=0;i<size;i++){
//源文件中读取数据到buff中
//srcFile.read(buff,1024);//(读了放到什么地方,一次读多少)
c=srcFile.get();//一个字符一个字符的从文件内容指针位置开始读
//源文件中读取不到数据了,结束
//if(c==EOF) break;//define EOF -1 代表文件结束,读取图片用文件结束符号会出错,谨慎使用
//把buff中数据写入到目的文件中
printf("%c",c);
dstFile.put(c);
}
cout<<"读完啦!"<<endl;
srcFile.close();
dstFile.close();
return 0;
}
自己写一个打包&解包的程序
思路:打包就是将诸多文件的大小和名字以及文件的内容(要复制文件内容必须知道文件大小才知道该在什么时候停止)全部存到一个文件中去。
pak文件:图片张数,每张图片的信息(多大,图片文件名),所有文件的内容(依次排列)
结构体:
struct fileMsg{
std::streamoff size;
char filename[256];
};
打包:
1.知道文件个数和文件名
#include <iostream>
#include <fstream>
using namespace std;
#include <string>
#include <cstring>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct fileMsg{
streamoff size;
char fileName[1024];
};
//获取文件大小
streamoff getFileSize(char* fileName){
fstream file;
streamoff size;
file.open(fileName,std::ios::in|ios::binary);
file.seekg(0,ios::end);
size=file.tellg();
file.seekg(ios::beg);
file.close();
return size;
}
int main(int argc, char** argv) {//argc为传给main()的命令行参数个数(包括自己写的可执行程序的名字,所以要-1),
//argv为一个字符串指针,代表整个命令行参数(即拖进去的文件),argv[i]为在DOS命令行中执行程序名后的第i个字符串 argv[0] 指向程序运行的全路径名
/*cout<<"总共有"<<argc-1<<"文件"<<endl;
int i;
for(i=1;i<argc;i++){
cout<<"第"<<i<<"张图片名为:"<<argv[i]<<endl;
} */
fstream dstFile;
//图片文件个数
int fileNum=argc-1;
//定义结构体
struct fileMsg* msg=new fileMsg[argc-1];
int i;
for(i=0;i<fileNum;i++){
strcpy(msg[i].fileName,argv[i+1]);//文件名赋值
msg[i].size=getFileSize(argv[i+1]);//每个文件文件大小赋值;
}
//创建打开目的地文件
dstFile.open("完成打包.pak",ios::out|ios::binary);
dstFile.write((char*)&fileNum,sizeof(int));//文件个数写入
dstFile.write( (char*)msg,fileNum*sizeof(struct fileMsg));//结构体写入
fstream srcFile;
for(int i=0;i<fileNum;i++){//循环写入文件内容
srcFile.open(msg[i].fileName,ios::in);
for(streamoff j=0;j<msg[i].size;j++){
dstFile.put(srcFile.get());
}
srcFile.close();
}
dstFile.close();
cout<<"完成打包"<<endl;
while(1);
return 0;
}
解包:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct fileMsg{
streamoff size;
char fileName[1024];
};
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
/* fstream srcFile;
struct fileMsg Msg;
srcFile.open("打包完成.pak",std::ios::in);
srcFile.read(&fileNum,sizeof(int));
for(j=0;j<fileNum;j++){
srcFile.read(&Msg[j].size,sizeof(streamoff))
int i=0;
char c;
while(1){
c=srcFile.get()
if(c==EOF) break;
Msg.fileName[i++]=c;
}
}
*/
fstream srcFile;
srcFile.open(argv[1],ios::in|ios::binary);
int filenum;
srcFile.read((char*)&filenum,sizeof(int));
fileMsg* msg= new fileMsg[filenum];
srcFile.read((char*)msg,filenum*sizeof(fileMsg));
int i;
fstream dstFile;
for(i=0;i<filenum;i++){
dstFile.open(msg[i].fileName,ios::out|ios::binary);
streamoff j;
for(j=0;j<msg[i].size;j++){
dstFile.put(srcFile.get());
}
dstFile.close();
}
srcFile.close();
while(1);
return 0;
}