首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ 文件與流操作:fstream、二進制讀寫、隨機訪問、編碼處理與高效能解析

     編輯:C++ 入門

C++ <fstream> 提供型別安全、RAII 管理的文件 I/O。本文涵蓋文本/二進制模式、格式化輸入輸出、隨機訪問、編碼轉換、大文件流式處理、高效能解析技巧。

核心流類別

類別頭文件功能典型用途
ofstream<fstream>輸出文件流寫入文本/二進制
ifstream<fstream>輸入文件流讀取文本/二進制
fstream<fstream>雙向文件流讀寫同一文件
ostringstream<sstream>輸出字符串流格式化構建字符串
istringstream<sstream>輸入字符串流解析字符串

打開模式標誌 (std::ios_base::openmode)


std::ofstream out("data.txt", std::ios::out | std::ios::trunc);     // 覆蓋寫入
std::ofstream app("log.txt", std::ios::out | std::ios::app);        // 追加
std::ifstream in("data.txt", std::ios::in);                         // 讀取
std::fstream rw("data.bin", std::ios::in | std::ios::out | std::ios::binary); // 二進制讀寫
std::ofstream ate("data.txt", std::ios::out | std::ios::ate);       // 打開定位末尾
// 組合:std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc

文本模式讀寫範例


// 寫入
{
    std::ofstream out("config.txt");
    out << "server=localhost\nport=8080\ndebug=true\n";
    out << std::fixed << std::setprecision(2) << 3.14159 << '\n';
}

// 讀取 (格式化提取)
{
    std::ifstream in("config.txt");
    std::string key, value;
    while (in >> key >> value) { /* 以空白分隔 */ }
    // 或逐行
    std::string line;
    while (std::getline(in, line)) { /* 處理整行 */ }
}

二進制模式讀寫


struct Record { int id; double value; char name[32]; };

// 寫入結構體陣列
{
    std::ofstream out("records.bin", std::ios::binary);
    Record recs[3] = {{1, 1.5, "A"}, {2, 2.5, "B"}, {3, 3.5, "C"}};
    out.write(reinterpret_cast<const char*>(recs), sizeof(recs));
}

// 讀取
{
    std::ifstream in("records.bin", std::ios::binary);
    Record rec;
    while (in.read(reinterpret_cast<char*>(&rec), sizeof(Record))) {
        std::cout << rec.id << ' ' << rec.value << ' ' << rec.name << '\n';
    }
}

隨機訪問:seekg / seekp / tellg / tellp


std::fstream io("data.bin", std::ios::in | std::ios::out | std::ios::binary);
io.seekg(0, std::ios::end);          // 定位末尾
std::streampos size = io.tellg();    // 獲取文件大小
io.seekg(0, std::ios::beg);          // 回到開頭

// 讀取第 N 個 Record (0-based)
auto read_record = [&](std::size_t n) {
    io.seekg(n * sizeof(Record), std::ios::beg);
    Record r; io.read(reinterpret_cast<char*>(&r), sizeof(Record));
    return r;
};

// 修改第 N 個 Record
auto write_record = [&](std::size_t n, const Record& r) {
    io.seekp(n * sizeof(Record), std::ios::beg);
    io.write(reinterpret_cast<const char*>(&r), sizeof(Record));
};

編碼處理:UTF-8 / UTF-16 / 本地編碼

  • 原始碼編碼:源文件保存為 UTF-8 (BOM 可選),編譯器 -finput-charset=UTF-8 (GCC) / 默認 UTF-8 (MSVC C++20 /utf-8)。
  • 執行期編碼:std::locale::global(std::locale("")) 設置 C 本地環境,影響 std::cout 輸出編碼。
  • 文件編碼轉換:C++20 std::codecvt 已棄用,推薦 iconv、ICU、boost::locale、或手寫 UTF-8 ↔ UTF-16 轉換。
  • Windows API:MultiByteToWideChar (CP_UTF8) / WideCharToMultiByte 配合 std::wifstream / std::wofstream (需 std::codecvt_utf8<wchar_t>,C++11/17/20 均可用但 C++20 棄用)。

大文件高效能處理

  • 記憶體映射:mmap (POSIX) / CreateFileMapping (Windows) / boost::iostreams::mapped_file — OS 頁面換入,隨機訪問極快。
  • 流式分塊讀取:固定緩衝區 (64KB-1MB) 循環 read/write,避免一次性載入。
  • 非同步 I/O:io_uring (Linux 5.1+)、IOCP (Windows)、boost::asio::posix::stream_descriptor — 高併發、低延遲。
  • 解析器:simdjson (JSON)、RapidCSV (CSV)、pugixml (XML) — SIMD 加速、單次掃描。

RAII 確保資源釋放


{
    std::ofstream out("data.txt"); // 構造打開
    out << "data";
} // 析構自動 close() + flush()

// 異常安全
try {
    std::ifstream in("data.txt");
    if (!in) throw std::runtime_error("open failed");
    // ...
} // 即使拋出異常,in 析構仍會 close()

常見錯誤與避坑

錯誤後果正確做法
未檢查 is_open() / fail()靜默失敗、讀取垃圾數據打開後立即檢查,或啟用 exceptions(std::ios::failbit)
文本模式讀二進制文件換行符轉換 (CRLF↔LF) 損壞數據二進制文件必須 std::ios::binary
while (!in.eof()) 循環最後一行重複處理while (in.read(...)) 或 while (std::getline(in, line))
混用 >> 和 getline()殘留換行符導致空行in.ignore(std::numeric_limits<streamsize>::max(), '\n'); 清除
大對象棧上分配緩衝區棧溢出std::vector<char> buf(size) 堆分配
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved