文章目录

  • 1.文件读写
  • 2.二进制文件的读写
  • 3.文件随机读写tellp、tellg、seekp、seekg

1.文件读写

  • 文本读写方式1:<<, >>,

  • 文本读写方式2:get, put,

  • read,

  • write

  • 文本模式打开与二进制模式打开的区别

  • eg:P60\01.cpp

#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;int main(void)
{ofstream fout( "test.txt");fout <<  "abc" <<  " " <<  200;//先把abc 200写入到文件中fout.close();ifstream fin( "test.txt");string s;int n;//fin>>n>>s;不按照顺序读取的话,会输出异常状态fin >> s >> n;//用文件输入流打开文件,并将其输出cout << s <<  " " << n << endl;return 0;
}
  • 测试:
  • eg:P60\02.cpp
#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;int main(void)
{ofstream fout1( "test2.txt");assert(fout1);char ch;//往一个文件中写入26个字母for ( int i =  0; i <  26; i++){ch =  'A' + i;fout1.put(ch);}fout1.close();ifstream fin1( "test2.txt");//读取文件到结束时,文件流处于EOF状态,类型转换指针void*指针会返回空指针,就跳出循环了while (fin1.get(ch)){cout << ch;}cout << endl;return 0;
}
  • 测试:写入文件的结果

    26个字节

  • eg:P60\03.cpp
#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;int main(void)
{/*如果以文本方式打开文件,写入字符的时候,遇到\n会做转换,写入\r不做转换如果以二进制方式打开文件写入字符的时候,遇到\n不会做转换windows平台\n会转换为 \r\nlinux平台保留不变mac系统\n转换为\r    *///默认以文本方式打开文件ofstream fout1( "test3.txt");fout1<<"ABC\r\n";fout1.close();return 0;
}
  • 测试:是6个字符,A,B,C,\r,\r,\n总共6个字符
  • eg:P60\04.cpp
#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;int main(void)
{/*(1)如果以文本方式打开文件,写入字符的时候,遇到\n会做转换,写入\r不做转换windows平台\n会转换为 \r\nlinux平台保留不变mac系统\n转换为\r    (2)如果以二进制方式打开文件写入字符的时候,遇到\n不会做转换(3)以文本方式打开文件,也可以写入二进制数据以二进制方式打开文件,也可以写入文本写入的数据是二进制还是文本,与打开方式无关,与写入使用的函数有关要写入二进制数据,应该用write,相应的读要用read*///以二进制方式打开ofstream fout1( "test3.txt", ios::out| ios::binary );fout1<<"ABC\r\n";fout1.close();return 0;
}
  • 测试:不做任何转换,输出5个字节

2.二进制文件的读写

  • 二进制文件不同于文本文件,它可用于任何类型的文件(包括文本文件)

  • 对二进制文件的读写可采取从istream类继承下来的成员函数read()和从ostream类继承下来的成员函数write()

  • 文件打开操作时使用枚举常量ios::binary,eg:ofstream fout(“binary.dat”, ios::out|ios::binary);

  • eg:P60\05.cpp

#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Test
{int a;int b;
};//测试:以文本方式打开文件,也可以写入二进制数据
//写入的数据是二进制还是文本,与打开方式无关,与写入使用的函数有关
int main(void)
{Test test = {100, 200};//以文本方式打开ofstream fout("test4.txt");//以二进制方式写入8个字节(将100在机器中的内存表示写入文件中),转化成char*fout.write(reinterpret_cast<char*>(&test), sizeof(Test));fout.close();//如何知道写入成功?可以读取出来Test test2;ifstream fin("test4.txt");fin.read(reinterpret_cast<char*>(&test2), sizeof(Test));cout<<test2.a<<" "<<test2.b<<endl;return 0;
}
  • 测试
    因为以文本方式打开是看不到这些字符的,因为它超过了ASCII码字符所表示的范围

  • eg:P60\07.cpp

#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Test
{int a;int b;
};//测试:以二进制方式打开文件,也可以写入文本
int main(void)
{Test test = {100, 200};//以二进制方式打开ofstream fout("test4.txt", ios::out|ios::binary);//c插入运算符<<是以文本方式写入数据的//虽然以二进制方式打开,但是写入的方式是文本的方式fout<<"abc"<<200;return 0;
}
  • 测试:

  • P60\08.cpp

#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Test
{int a;string b;//string对象string c;
};//MyString类大小总是4字节,与字符串str无关
//同样string只与其成员有关,他里面的成员就是一些指针,不同平台不一样,当前平台是32字节,其他平台可能是16字节,因为持有的数据成员不同
class MyString
{char* str;
}int main(void)
{Test t1;t1.a = 100;t1.b = "xxxabcdddddddddddddddddddddddddddddddddddddddddddddddffffffffffffffffffffffffff";t1.c = "yyyffffffffffffffffffffffffffffffffddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";//下面的写入方式是不行的//因为每次写入的时候,并不是将字符串b和c的所有内容写入到文件中,总是写入了68字节而已(struct Test:4+32+32)//只是写将string中的成员指针写进去了,而没有将指针所指向的内存写入进去ofstream fout("test6.txt", ios::out|ios::binary);fout.write((char*)&t1, sizeof(t1));fout.close();ifstream fin("test6.txt", ios::out|ios:binary);Test t2;fin.read((char*)&t2, sizeof(Test));cout<<t2.a<<" "<<t2.b<<" "<<t2.c<<endl;fin.close();//string类型的大小总是32字节//计算一个类型或者说一个类型所对应对象的大小,与字符串内容无关cout<<sizeof(Test)<<endl;string a = "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";cout<<sizeof(string)<<endl;cout<<sizeof(a)<<endl;return 0;
}
  • 测试:
    字符串超过32字节

    写入的文件总是68字节

  • eg:P60\09.cpp
#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Test
{int a;string b;//string对象string c;
};//MyString类大小总是4字节,与字符串str无关
//同样string只与其成员有关,他里面的成员就是一些指针,不同平台不一样,当前平台是32字节,其他平台可能是16字节,因为持有的数据成员不同
class MyString
{char* str;
}int main(void)
{Test t1;t1.a = 100;t1.b = "xxxabcdddddddddddddddddddddddddddddddddddddddddddddddffffffffffffffffffffffffff";t1.c = "yyyffffffffffffffffffffffffffffffffddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";// //下面的写入方式是不行的// //因为每次写入的时候,并不是将字符串b和c的所有内容写入到文件中,总是写入了68字节而已(struct Test:4+32+32)// ofstream fout("test6.txt", ios::out|ios::binary);// fout.write((char*)&t1, sizeof(t1));// fout.close();// ifstream fin("test6.txt", ios::out|ios:binary);// Test t2;// fin.read((char*)&t2, sizeof(Test));// cout<<t2.a<<" "<<t2.b<<" "<<t2.c<<endl;// fin.close();// //string类型的大小总是32字节// //计算一个类型或者说一个类型所对应对象的大小,与字符串内容无关// cout<<sizeof(Test)<<endl;// string a = "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";// cout<<sizeof(string)<<endl;// cout<<sizeof(a)<<endl;//正确的写入方式:一个一个写入ofstream fout("test6.txt", ios::out|ios::binary);//写入字符串的时候,最好先写入字符串的长度,然后写入字符串实际数据fout.write((char*)&t1.a, sizeof(int));int len;len = t1.b.length();fout.write((char*)&len, sizeof(int));fout.write((char*)&t1.b.data(), t1.b.length());len = t1.c.length();fout.write((char*)&len, sizeof(int));fout.write((char*)&t1.c.data(), t1.c.length());//data()实际上调用的是c_str()方法fout.close();ifstream fin("test6.txt", ios::out|ios:binary);Test t2;fin.read((char*)&t2.a, sizeof(int));fin.read((char*)&len, sizeof(int)); //读第二个字符串的长度t2.b.resize(len);fin.read((char*)&t2.b[0], len);fin.read((char*)&len, sizeof(int));t2.b.resize(len);fin.read((char*)&t2.c[0], len);cout<<t2.a<<" "<<t2.b<<" "<<t2.c<<endl;fin.close();return 0;
}
  • 测试:


    看乱码,首先是4个字节的整数,然后又是4个字节的整数,表示第一个字符串的长度,然后是第二个字符串的长度

  • write()成员函数
函数功能:以字节为单位向文件流中写入整块数据,最有价值的应用可以处理结构体变量和类对象
函数原型:ostream& write( const char* pch, int nCount );函数参数:
pch 写入的数据的指针
nCount 写入数据的字节大小
  • read() 成员函数
函数功能:从文件流中读出整块数据
函数原型:istream& read( char* pch, int nCount ); 函数参数:
pch 用来接收数据的指针
nCount 读取的字节数的大小

3.文件随机读写tellp、tellg、seekp、seekg

  • 当前文件流活动指针
    (1)文件流指针用以跟踪发生 I/O 操作的位置
    (2)每当从流中读取或写入一个字符,当前活动指针就会向前移动
    (3)当打开方式中不含有ios::ate或ios::app选项时,则文件指针被自动移到文件的开始位置,即字节地址为0的位置。

  • 文件的随机读写 seekp和seekg:定位文件指针

函数功能
seekp:设置输出文件流的文件流指针位置
seekg:设置输入文件流的文件流指针位置函数原型:ostream& seekp( streampos pos );定位到某一个位置pos,基准点是文件的开头指定的ostream& seekp( streamoff off, ios::seek_dir dir );基准点可以是开头,结尾,或者文件当前位置,类似于Linux下的fseek,lseekistream& seekg( streampos pos );istream& seekg( streamoff off, ios::seek_dir dir );函数参数
pos:新的文件流指针位置值
off:需要偏移的值
dir:搜索的起始位置
  • 文件的随机读写tellp和tellg:获取当前文件流活动指针
输出流用tellp
输入流用tellg函数功能
tellp:获得输出的文件流指针的当前位置,以字节为单位
tellg:获得输入的文件流指针的当前位置,以字节为单位函数原型:
streampos tellp();
streampos tellg();函数返回值:实际上是一个long类型
  • 其他
C库
fseek,ftellLinux系统调用
lseek
lseek(fd, 0, SEEK_CUR)seekp,seekg与C库中fseek相互对应(C库不区分输入流和输出流)
tellp,tellg与C库中ftell相互对应seekp,seekg与Linux系统调用中lseek相互对应
Linux系统调用没有对应的tell函数,而可以通过lseek(fd, 0, SEEK_CUR)实现类似功能,其返回值为当前文件指针的位置
  • seek_dir
dir参数用于对文件流指针的定位操作上,代表搜索的起始位置
在ios中定义的枚举类型:enum seek_dir {beg, cur, end};每个枚举常量的含义:
ios::beg:文件流的起始位置
ios::cur:文件流的当前位置
ios::end:文件流的结束位置
  • eg:P60\10.cpp
#include <cassert>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void)
{ifstream fin("test7.txt");//文件输入流不会创建文件//如果文件不存在,打开会失败assert(fin);fin.seekg(2);//定位到字符cchar ch;fin.get(ch);cout<<ch<<endl;//输出最后一个字符//定位到文件结尾处,向前-1//文件流指针指向了末尾的地方fin.seekg(-1, ios::end);fin.get(ch);cout<<ch<<endl;//用以下方法可以获取文件的大小//获取文件流指针的位置//0是结束符的位置fin.seekg(0, ios::end);streampos pos = fin.tellg();cout<<pos<<endl;return 0;
}
  • 测试:

    当前文件大小是7个字节

(P60)io流类库:文件读写,二进制文件的读写,文件随机读写tellp、tellg、seekp、seekg相关推荐

  1. IO流技术【Properties类介绍、文件切割与合并】

    IO流技术[Properties类介绍.文件切割与合并] 1.Properties类介绍 1.1.Properties的基本功能 Properties特点: 1.Hashtable的子类,map集合中 ...

  2. JAVA mac系统io文件流_Java IO流基础1--IO的分类体系与文件流

    什么是IO流 Java中的IO 了解什么是IO流之前,要先知道什么是IO.IO,就是in和out(即输入和输出),指应用程序和外部设备之间的数据传递,常见的外部设备包括文件.管道.网络连接等. 流的概 ...

  3. java中关于IO流的知识总结(重点介绍文件流的使用)

    今天做软件构造实验一的时候,用到了java文件流的使用,因为之前学的不是很踏实,于是决定今天好好总结一下, 也方便以后的回顾. 首先,要分清IO流中的一些基础划分: 按照数据流的方向不同可以分为:输入 ...

  4. JAVA中常用IO流类:BufferedReader和BufferedWriter读取文件操作

    一.BufferedReader 字符串缓冲读取类 构造方法:bufferedWriter bf = new bufferedWriter(Writer out ); 主要方法:void write( ...

  5. 综合应用题:多线程复制文件(知识点:多线程、随机读写流)

    要求:使用多线程复制一个文件(使用多线程复制一个文件可以加快文件的复制速度) 代码: package 多线程复制文件;import java.io.File; import java.io.FileN ...

  6. HDFS以IO流的形式上传和下载文件案例

    Maven工程HdfsClient的创建,对应包和类的创建参考HDFS文件上传.下载和删除案例 1.文件上传 //把本地的banzhang.txt文件上传到HDFS的根目录@Testpublic vo ...

  7. 使用IO流将数据库中数据生成一个文件,结果使用Notepad++打开部分数据结尾出现NUL...

    场景描述: 项目中通过java代码中从数据库中查询一系列数据,对数据做相应处理,然后通过字符流将数据写如一个新生成的文件中,将该项目部署在linux服务器上,最后生成的文件拿到本地使用notepad+ ...

  8. 从零开始学C++之IO流类库(四):输出流格式化(以操纵子方式格式化,以ios类成员函数方式格式化)

    一.以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符.把它们作为插入操作符<<的输出对象即可.如setiosflags.setw.set ...

  9. Java写文件导致io过高_161108、Java IO流读写文件的几个注意点

    平时写IO相关代码机会挺少的,但却都知道使用BufferedXXXX来读写效率高,没想到里面还有这么多陷阱,这两天突然被其中一个陷阱折腾一下:读一个文件,然后写到另外一个文件,前后两个文件居然不一样? ...

最新文章

  1. 云计算如何帮助直播行业发展
  2. 正则表达式教程手册、正则一点通(Chinar出品)
  3. 超适合新手的Oracle查询语句
  4. 在python中嵌入c/c++
  5. One order time zone
  6. C#生成二维码(含解码)
  7. 天池 在线编程 高效作业处理服务(01背包DP)
  8. fiddler设置中文版本_突破安卓7.0以上版本WX小程序抓包篇
  9. js怎么动态加载js文件(JavaScript性能优化篇)
  10. CentOS 7安装配置vsftpd做FTP服务
  11. 17年北邮计算机应用基础,2017计算机应用基础考试题及答案
  12. Swagger Annotation 详解(建议收藏)
  13. 输出保留3位小数的浮点数
  14. pytorch固定BN层参数
  15. 第1章 iFIX概述
  16. android手机解除root,手机一键ROOT以后如何解除?手机root后怎么恢复
  17. 如何压缩文件到最小——压缩参数调整 for 7z
  18. 华为刷原生android,教你如何体验(刷)原生安卓8.0
  19. python(14)--集合
  20. java购物车设计_Java简单购物车设计

热门文章

  1. var 和 let的区别_let 和 var的区别
  2. 食品经营许可证没过期也要换?详细解读来了~
  3. IMU姿态融合(MPU9250从校正到滤波步骤)
  4. java基于ssm springboot+vue的共享充电宝系统 element
  5. Cygwin安装教程 linux模拟器
  6. iPad 上最强 IDE,支持 20 多种开发语言,还开源了
  7. 2021.10.12 lesson06——母婴商场分析
  8. 荣耀会升级鸿蒙吗,华为高管确认:6月全面推升鸿蒙系统,官方账号正式开通...
  9. leetcode刷题 638大礼包
  10. java基本语法 --- 字符型变量的基本说明