;
在抛出异常崩溃前,刷新流缓冲区,会将字符串写入到文件。
C++ 中使用 open() 打开的文件,在读写操作执行完毕后,应及时调用 close() 方法关闭文件,或者对文件执行写操作后及时调用 flush() 方法刷新输出流缓冲区。
文件读写方法
1、使用 << 与 >> 实现读写文件:使用于文本形式读写文件;
2、使用read() 和 write() 成员方法读写文件:适用于二进制读写文件。
ostream::write()方法写文件
1 ostream & write(char* buffer, int count);
2 //buffer 用于指定要写入文件的二进制数据的起始位置;
3 //count 用于指定写入字节的个数
函数返回的是引用形式的对象,obj.write() 方法的返回值就是对 obj 对象的引用
注意:write方法会从文件写指针的位置将二进制数据写入,默然指向开头,若以 ios::app方式打开,则指向文件末尾
istream::read()方法读文件
1 istream & read(char* buffer, int count);、
2 //buffer 用于指定读取字节的起始位置
3 //count 指定读取字节的个数
移动和获取文件读写指针(seekp、seekg、tellg、tellp)
ostream & seekp (int offset, int mode);
istream & seekg (int offset, int mode);
mode 代表文件读写指针的设置模式,有以下三种选项:
ios::beg:让文件读指针(或写指针)指向从文件开始向后的 offset 字节处。offset 等于 0 即代表文件开头。在此情况下,offset 只能是非负数。
ios::cur:在此情况下,offset 为负数则表示将读指针(或写指针)从当前位置朝文件开头方向移动 offset 字节,为正数则表示将读指针(或写指针)从当前位置朝文件尾部移动 offset字节,为 0 则不移动。
ios::end:让文件读指针(或写指针)指向从文件结尾往前的 |offset|(offset 的绝对值)字节处。在此情况下,offset 只能是 0 或者负数
int tellg();
int tellp();
得到当前读写指针的具体位置:
ifstream 类和 fstream 类还有 tellg 成员函数,能够返回文件读指针的位置;
ofstream 类和 fstream 类还有 tellp 成员函数,能够返回文件写指针的位置。
要获取文件长度,可以用 seekg 函数将文件读指针定位到文件尾部,再用 tellg 函数获取文件读指针的位置,此位置即为文件长度。
1 std::vector<std::vector<char>> Avs::adjustLUT(
2 const std::string& calFileURL, const std::vector<std::string>& maskFileURLs,
3 const std::vector<AVS_ADJUST_S>& adjustParams) {
4 assert(maskFileURLs.size() == adjustParams.size());
6 std::ifstream calFile(calFileURL, std::ios::binary); //binary:以二进制方式打开文件
7 assert(calFile.is_open());
9 std::vector<char> calBuffer(AVS_CALIBRATION_FILE_LENGTH);
10 calFile.read(calBuffer.data(), calBuffer.size()); //从calFile读取size()大小的数据到calBuffer
12 //将数个maskFile存入到maskBuffer容器中
13 std::vector<std::vector<char>> maskBuffers;
14 for (auto& url : maskFileURLs) {
15 std::ifstream file(url, std::ios::binary); //将maskFile与file对象绑定
16 assert(file.is_open());
17 file.seekg(0, file.end); //将文件指针指向文件尾
19 //创建一个大小为文件长度大小的容器buffer
20 std::vector<char> buffer(file.tellg()); //tellg 函数获取文件读指针的位置,此位置即为文件长度
21 file.seekg(0, file.beg); //文件指针指向文件开始处
22 file.read(buffer.data(), buffer.size()); //从file(maskFile)读取size大小的数据到buffer
23 maskBuffers.push_back(std::move(buffer)); //每循环一次,在maskBuffer容器后加入一个Buffer
24 }
26 ...
C++ 标准库使用比如vector::push_back 等这类函数时,会对参数的对象进行复制,连数据也会复制.这就会造成对象内存的额外创建, 本来原意是想把参数push_back进去就行了,通过std::move,可以避免不必要的拷贝操作。
std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝所以可以提高利用效率,改善性能.。
对指针类型的标准库对象并不需要这么做.
原lvalue值被moved from之后值被转移,所以为空字符串.。一般在代码段的末尾使用move(value),被转移所有权的value不可以再次被使用
move用法示例:
//摘自https://zh.cppreference.com/w/cpp/utility/move
#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
std::string str = "Hello";
std::vector<std::string> v;
//调用常规的拷贝构造函数,新建字符数组,拷贝数据
v.push_back(str);
std::cout << "After copy, str is \"" << str << "\"\n";
//调用移动构造函数,掏空str,掏空后,最好不要使用str
v.push_back(std::move(str));
std::cout << "After move, str is \"" << str << "\"\n";
std::cout << "The contents of the vector are \"" << v[0]
<< "\", \"" << v[1] << "\"\n";
After copy, str is "Hello"
After move, str is ""
The contents of the vector are "Hello", "Hello"