昨天的文章中叙述了C++17的文件系统操作,极大的方便了对于文件夹的操作,见链接[现代C++]文件系统操作。今天将更深一步的讲解文件的读写。
C方法读写文件
C++沿袭了C的读写文件的方法,示例代码如下,(此方法可以忽略,直接读下一节)
constexpr int buffer_length = 12;
void test_fwrite(){
//"wb"表征以二进制写的形式打开文件,
//不同的模式对应不同的类型
auto file = fopen("d://1.txt","wb");
if (!file){
std::cout<<"failed to open file\n";
}
char* buffer = (char*)malloc(buffer_length);
std::memset(buffer,0,buffer_length);
for (size_t i = 0; i < buffer_length; i++){
char c = 65+i;
std::memcpy(buffer+i,&c,1);
}
fwrite(buffer,1,buffer_length,file);
free(buffer);
fclose(file);
}
void test_fread(){
//"rb"表征以二进制读的形式打开文件
//不同的模式对应不同的类型
auto file = fopen("d://1.txt", "rb");
if (!file){
std::cout << "failed to open file\n";
}
fseek(file, 0, SEEK_END);
size_t fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
char* buffer = (char*)malloc(fileSize);
std::memset(buffer, 0, fileSize);
auto read_size = fread(buffer, 1, buffer_length, file);
for (size_t i = 0; i < read_size; i++){
std::cout<<*((char*)buffer+i)<<"\t";
}
std::cout<<"\n";
free(buffer);
fclose(file);
}
由以上的示例代码可知,打开的文件必须在使用完后调用fclose关闭。一旦忘记关闭打开的文件便会出现资源泄露。
fstream读写文件
fstream可以用来读写文件,其实自C++98以来fstream已在标准库中,只是C++11及以后扩展了其功能,改善了文件处理方式。<fstream>C++的标准库<fstream>提供了std::ifstream(输入流)、std::ofstream(输出流)和std::fstream(输入输出流)三个类,分别用于文件的读取、写入和读写操作。
示例代码如下:
#include<fstream>
#include<string>
void writeFile(conststd::string&filename) {
//std::ios_base::out表征输出模式
//std::ofstream outFile;
//outFile.open(filename,std::ios_base::out);
std::ofstream outFile(filename,std::ios_base::out);
if (!outFile) {
std::cerr << "Failed to open the file for writing." << std::endl;
return;
}
outFile << "Hello, Modern C++ File Writing!" << std::endl;
// 自动关闭文件,也可以显式调用outFile.close();
}
void readFile(conststd::string&filename) {
//std::ios_base::in表征输入模式
//std::ios_base::binary表征二进制模式
std::ifstream inFile(filename, std::ios_base::in|std::ios_base::binary);
if (!inFile) {
std::cerr << "Failed to open the file for reading." << std::endl;
return;
}
std::string line;
while (std::getline(inFile, line)) {
std::cout << line << std::endl;
}
// 文件自动关闭
}
由如上代码可知:
结合文件系统的文件读写
在文件读写之前对于路径有效性进行判断是非常有必要的,详细的路径检查见链接[现代C++]文件系统操作。简单的示例代码如下:
#include<fstream>
#include<filesystem>
void writeToFileUsingFS(conststd::filesystem::path&filePath) {
std::ofstream outFile(filePath);
if (!outFile) {
std::cerr << "Failed to open " << filePath << " for writing." << std::endl;
return;
}
outFile << "File operation with std::filesystem." << std::endl;
}
void readFromFileUsingFS(conststd::filesystem::path&filePath) {
if (!std::filesystem::exists(filePath)) {
std::cerr << filePath << " does not exist." << std::endl;
return;
}
std::ifstream inFile(filePath);
if (!inFile) {
std::cerr << "Failed to open " << filePath << " for reading." << std::endl;
return;
}
std::string content((std::istreambuf_iterator<char>(inFile)),std::istreambuf_iterator<char>());
std::cout << content << std::endl;
}
由以上代码可知,在读文件前对文件进行存在性检测,增加代码的健壮性。
结语
本文在指出C方法读写文件缺陷的基础上,引出了fstream提供的读写文件新方法。fstream在RAII思想加持下完成文件资源的自动回收。继而提出了结合std::filesystem和fstream的方法,提高读写文件的健壮性。