核心流操作類
| 類 | 頭文件 | 用途 |
ofstream | | 寫文件 (output file stream) |
ifstream | | 讀文件 (input file stream) |
fstream | | 讀寫文件 |
stringstream | | 內存字符串流 |
基本文件讀寫示例
#include
#include
#include
#include
int main() {
// 寫入多個文件
for (int i = 0; i < 3; ++i) {
char filename[64];
sprintf(filename, "t%d.txt", i); // 格式化文件名
std::ofstream ofs(filename);
ofs << 0 << std::endl; // 寫入整數 + 換行
ofs.close(); // RAII 會自動 close,顯式關閉也可
}
// 讀取並驗證
for (int i = 0; i < 3; ++i) {
char filename[64];
sprintf(filename, "t%d.txt", i);
std::ifstream ifs(filename);
int val;
ifs >> val; // 格式化讀取
std::cout << filename << ": " << val << std::endl;
}
return 0;
}
關鍵技術點
sprintf/snprintf:生成序列文件名
operator<</operator>>:類型安全的格式化 IO
- RAII:流對象析構時自動
close()、刷新緩衝區
- 錯誤檢查:
if (!ofs)、if (ifs.fail())
目錄遍歷:獲取文件列表 (POSIX/Linux)
#include
#include
#include
struct FileNode {
std::string name;
// 可擴展:size, time, type 等
};
std::vector getFiles(const std::string& dirPath) {
std::vector files;
DIR* dp = opendir(dirPath.c_str());
if (!dp) return files;
struct dirent* entry;
while ((entry = readdir(dp)) != nullptr) {
// 跳過 . 和 ..
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
files.push_back({entry->d_name});
}
closedir(dp);
return files;
}
// Windows 版本:_findfirst/_findnext 或 std::filesystem (C++17)
現代 C++17 文件系統庫 (std::filesystem)
#include
#include
namespace fs = std::filesystem;
void listFiles(const std::string& path) {
for (const auto& entry : fs::directory_iterator(path)) {
std::cout << entry.path().filename()
<< (entry.is_directory() ? " [DIR]" : " [FILE]")
<< " size: " << entry.file_size() << '\n';
}
}
void recursiveFind(const std::string& path, const std::string& ext) {
for (const auto& entry : fs::recursive_directory_iterator(path)) {
if (entry.is_regular_file() && entry.path().extension() == ext)
std::cout << entry.path() << '\n';
}
}
格式化讀取進階
// 讀取整行(含空格)
std::string line;
while (std::getline(ifs, line)) {
// 處理 line
}
// 字符串流解析行內字段
std::istringstream iss(line);
std::string field;
while (iss >> field) { /* ... */ }
// 讀取二進制數據
std::vector buffer(1024);
ifs.read(buffer.data(), buffer.size());
std::streamsize actual = ifs.gcount();
最佳實踐檢查清單
☐ 文件打開後立即檢查 if (!stream)
☐ 文本模式用 >>/getline,二進制用 read/write
☐ 大文件分塊讀取,避免一次性載入內存
☐ 跨平台優先用 std::filesystem (C++17)
☐ 錯誤處理:exceptions() 設置異常掩碼或手動檢查 fail()/bad()
☐ 寫入關鍵數據後 flush() 或 sync_with_stdio(false) 提高性能
總結
C++ 流式 IO 提供類型安全、可擴展的文本/二進制文件操作。
RAII 保證資源自動釋放。
C++17 std::filesystem 統一了跨平台目錄操作。
格式化讀寫 (>>/<<) 是日常首選,二進制場景用 read/write。