插件窝 干货文章 C++在Linux中如何进行文件操作

C++在Linux中如何进行文件操作

文件 include std 214    来源:    2025-05-09

C++在Linux中的文件操作指南

在Linux环境下,C++提供了多种文件操作方式,主要包括标准C++库(fstream)和POSIX/Linux系统调用。以下是主要方法和示例:

1. 使用C++标准库(fstream)

这是最常用的跨平台文件操作方式。

基本文件操作

#include <fstream>
#include <iostream>
#include <string>

int main() {
    // 写入文件
    std::ofstream outFile("example.txt");
    if (outFile.is_open()) {
        outFile << "Hello, Linux file system!\n";
        outFile << "This is a second line.\n";
        outFile.close();
    } else {
        std::cerr << "Unable to open file for writing\n";
        return 1;
    }

    // 读取文件
    std::ifstream inFile("example.txt");
    std::string line;
    if (inFile.is_open()) {
        while (getline(inFile, line)) {
            std::cout << line << '\n';
        }
        inFile.close();
    } else {
        std::cerr << "Unable to open file for reading\n";
        return 1;
    }

    return 0;
}

二进制文件操作

#include <fstream>

struct Data {
    int x;
    double y;
    char name[20];
};

int main() {
    // 写入二进制文件
    Data data = {10, 3.14, "Linux"};
    std::ofstream binOut("data.bin", std::ios::binary);
    if (binOut) {
        binOut.write(reinterpret_cast<char*>(&data), sizeof(Data));
        binOut.close();
    }

    // 读取二进制文件
    Data readData;
    std::ifstream binIn("data.bin", std::ios::binary);
    if (binIn) {
        binIn.read(reinterpret_cast<char*>(&readData), sizeof(Data));
        binIn.close();
        std::cout << "Read: " << readData.x << ", " << readData.y << ", " << readData.name << "\n";
    }

    return 0;
}

2. 使用POSIX系统调用

对于更底层的操作或需要特定Linux功能时使用:

#include <fcntl.h>      // open()
#include <unistd.h>     // read(), write(), close()
#include <sys/stat.h>   // fstat()
#include <cerrno>       // errno
#include <cstring>      // strerror()
#include <iostream>

int main() {
    // 打开文件 (O_CREAT | O_WRONLY | O_TRUNC 表示创建/只写/清空)
    int fd = open("posix_example.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (fd == -1) {
        std::cerr << "Open failed: " << strerror(errno) << "\n";
        return 1;
    }

    // 写入文件
    const char* text = "POSIX file operations in Linux\n";
    ssize_t bytesWritten = write(fd, text, strlen(text));
    if (bytesWritten == -1) {
        std::cerr << "Write failed: " << strerror(errno) << "\n";
        close(fd);
        return 1;
    }

    close(fd);

    // 读取文件
    fd = open("posix_example.txt", O_RDONLY);
    if (fd == -1) {
        std::cerr << "Open for read failed: " << strerror(errno) << "\n";
        return 1;
    }

    char buffer[256];
    ssize_t bytesRead = read(fd, buffer, sizeof(buffer)-1);
    if (bytesRead == -1) {
        std::cerr << "Read failed: " << strerror(errno) << "\n";
        close(fd);
        return 1;
    }

    buffer[bytesRead] = '\0'; // 确保字符串终止
    std::cout << "Read content: " << buffer;

    close(fd);
    return 0;
}

3. 文件和目录管理

使用C++17文件系统库(跨平台)

#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;

int main() {
    // 创建目录
    fs::create_directory("test_dir");

    // 检查文件/目录是否存在
    if (fs::exists("test_dir")) {
        std::cout << "Directory exists\n";
    }

    // 复制文件
    fs::copy("example.txt", "test_dir/example_copy.txt");

    // 遍历目录
    for (const auto& entry : fs::directory_iterator("test_dir")) {
        std::cout << entry.path() << "\n";
    }

    // 删除文件或目录
    fs::remove("test_dir/example_copy.txt");
    fs::remove_all("test_dir");  // 递归删除

    return 0;
}

使用Linux系统调用

#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <iostream>

int main() {
    // 创建目录
    mkdir("linux_dir", 0755);

    // 检查文件/目录是否存在
    struct stat info;
    if (stat("linux_dir", &info) == 0) {
        if (S_ISDIR(info.st_mode)) {
            std::cout << "Directory exists\n";
        }
    }

    // 遍历目录
    DIR* dir = opendir("linux_dir");
    if (dir) {
        dirent* entry;
        while ((entry = readdir(dir)) != nullptr) {
            std::cout << entry->d_name << "\n";
        }
        closedir(dir);
    }

    // 删除目录
    rmdir("linux_dir");

    return 0;
}

4. 内存映射文件(高效处理大文件)

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>

int main() {
    const char* filename = "large_file.bin";
    const size_t fileSize = 1024 * 1024; // 1MB

    // 创建并设置文件大小
    int fd = open(filename, O_RDWR | O_CREAT, 0644);
    ftruncate(fd, fileSize);

    // 内存映射
    void* mapped = mmap(nullptr, fileSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mapped == MAP_FAILED) {
        std::cerr << "mmap failed\n";
        close(fd);
        return 1;
    }

    // 访问映射内存
    char* data = static_cast<char*>(mapped);
    data[0] = 'A';
    data[fileSize-1] = 'Z';

    // 同步到磁盘
    msync(mapped, fileSize, MS_SYNC);

    // 清理
    munmap(mapped, fileSize);
    close(fd);

    return 0;
}

最佳实践建议

  1. 错误处理:始终检查文件操作是否成功,并处理可能的错误
  2. 资源管理:使用RAII(如fstream自动关闭)或确保手动释放资源
  3. 权限设置:在Linux中创建文件时设置适当的权限(如0644)
  4. 性能考虑
    • 对于小文件,C++流通常足够
    • 对于大文件或高性能需求,考虑内存映射或直接系统调用
  5. 跨平台:如果需要跨平台,优先使用C++标准库

常见问题解决

  1. 权限被拒绝

    • 检查程序是否有足够的权限
    • 检查文件是否已被其他进程锁定
  2. 文件不存在

    • 使用前检查文件是否存在
    • 使用适当的打开标志(O_CREAT)
  3. 资源泄漏

    • 确保所有打开的文件描述符都被关闭
    • 考虑使用智能指针管理资源
  4. 跨文件系统问题

    • 某些操作(如重命名)在跨文件系统时可能失败
    • 对于大文件移动,考虑复制+删除原文件

希望这份指南能帮助您在Linux环境下有效地进行C++文件操作!