文件操作

发布于:2025-06-21 ⋅ 阅读:(13) ⋅ 点赞:(0)

C/C++文件操作基础概念

文件操作是程序与外部存储设备交互的重要方式,主要涉及文件的创建、读写、关闭等操作。在C语言中通过<stdio.h>提供的函数实现,C++则提供<fstream>库进行面向对象封装。

文件打开模式

C语言常用文件打开模式:

  • "r":只读(文件必须存在)
  • "w":只写(创建新文件或清空现有文件)
  • "a":追加(写入数据到文件末尾)
  • "r+":读写(文件必须存在)
  • "w+":读写(创建新文件或清空现有文件)
  • "b":二进制模式(与上述模式组合使用,如"wb"

C++对应模式:

  • ios::in:读
  • ios::out:写
  • ios::app:追加
  • ios::binary:二进制

C语言文件操作函数

FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);

C++文件流类

主要包含三个类:

  • ifstream:输入文件流(读操作)
  • ofstream:输出文件流(写操作)
  • fstream:双向文件流(读写操作)

文本文件读写示例

C语言文本文件写入:

FILE *fp = fopen("test.txt", "w");
if(fp) {
    fprintf(fp, "Hello World\n");
    fclose(fp);
}

C++文本文件读取:

#include <fstream>
#include <string>
std::ifstream infile("test.txt");
std::string line;
while(std::getline(infile, line)) {
    // 处理每行数据
}
infile.close();

二进制文件操作

C语言二进制写入:

struct Data { int x; float y; };
Data d = {10, 3.14f};
FILE *fp = fopen("data.bin", "wb");
if(fp) {
    fwrite(&d, sizeof(Data), 1, fp);
    fclose(fp);
}

C++二进制读取:

#include <fstream>
struct Data { int x; float y; };
Data d;
std::ifstream in("data.bin", std::ios::binary);
in.read(reinterpret_cast<char*>(&d), sizeof(Data));
in.close();

文件位置控制

获取当前文件位置:

long pos = ftell(fp);  // C
streampos pos = file.tellg();  // C++

设置文件位置:

fseek(fp, 0, SEEK_SET);  // 移动到文件开头
file.seekg(0, ios::beg);  // C++等效

错误处理

检查文件操作是否成功:

if(ferror(fp)) { /* 处理错误 */ }
if(feof(fp)) { /* 到达文件末尾 */ }

C++检查:

if(!file.is_open()) { /* 文件未打开 */ }
if(file.fail()) { /* 操作失败 */ }

 文件操作中应始终检查操作是否成功。

FILE *file = fopen("nonexistent.txt", "r");
if (file == NULL) {
    perror("Error opening file");
}

ifstream inFile("nonexistent.txt");
if (!inFile) {
    cerr << "Error opening file" << endl;
}

跨平台注意事项

Windows和Linux系统在文本文件处理上有差异:

  • 换行符:Windows使用\r\n,Linux使用\n
  • 路径分隔符:Windows用\,Linux用/ 建议使用/作为路径分隔符,它在Windows和Linux上都兼容。

C和C++语言提供了多种文件操作方法,包括标准C库函数和C++的fstream类。文件操作通常涉及打开、读写、关闭等基本操作。

标准C库文件操作

标准C库使用FILE结构体和一系列函数进行文件操作,主要函数包括fopen、fclose、fread、fwrite等。

FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

文件打开模式包括:

  • "r":只读
  • "w":只写(创建新文件或清空现有文件)
  • "a":追加
  • "r+":读写
  • "w+":读写(创建新文件或清空现有文件)
  • "a+":读写(追加)
C++ fstream文件操作

C++通过fstream、ifstream和ofstream类提供更面向对象的文件操作方式。

#include <fstream>
using namespace std;

ofstream outFile("filename.txt"); // 输出文件流
ifstream inFile("filename.txt");  // 输入文件流
fstream ioFile("filename.txt", ios::in | ios::out); // 输入输出文件流

文件打开模式标志:

  • ios::in:输入
  • ios::out:输出
  • ios::app:追加
  • ios::ate:打开时定位到文件末尾
  • ios::binary:二进制模式
  • ios::trunc:截断文件

文本文件读写示例

C语言文本文件读写
FILE *file = fopen("example.txt", "w");
if (file != NULL) {
    fprintf(file, "Hello, World!\n");
    fclose(file);
}

file = fopen("example.txt", "r");
if (file != NULL) {
    char buffer[100];
    while (fgets(buffer, sizeof(buffer), file) != NULL) {
        printf("%s", buffer);
    }
    fclose(file);
}

C++文本文件读写
#include <iostream>
#include <fstream>
#include <string>

// 写入文件
ofstream outFile("example.txt");
if (outFile.is_open()) {
    outFile << "Hello, World!" << endl;
    outFile.close();
}

// 读取文件
ifstream inFile("example.txt");
string line;
if (inFile.is_open()) {
    while (getline(inFile, line)) {
        cout << line << endl;
    }
    inFile.close();
}

文件定位与状态检查

文件操作中经常需要检查状态或移动文件指针。

C语言文件定位
FILE *file = fopen("example.txt", "r+");
if (file != NULL) {
    fseek(file, 0, SEEK_END); // 移动到文件末尾
    long size = ftell(file);  // 获取文件大小
    rewind(file);             // 回到文件开头
    fclose(file);
}

C++文件定位
fstream file("example.txt", ios::in | ios::out);
if (file.is_open()) {
    file.seekg(0, ios::end);     // 移动读指针
    streampos size = file.tellg();
    file.seekp(0, ios::beg);     // 移动写指针
    file.close();
}

临时文件创建

临时文件常用于中间数据处理。

C语言临时文件
FILE *tmpFile = tmpfile();
if (tmpFile != NULL) {
    fprintf(tmpFile, "Temporary data");
    rewind(tmpFile);
    // 使用临时文件...
    fclose(tmpFile); // 自动删除
}
C++临时文件
#include <cstdio>

FILE *tmpFile = tmpfile();
if (tmpFile != nullptr) {
    fputs("Temporary data", tmpFile);
    rewind(tmpFile);
    // 使用临时文件...
    fclose(tmpFile);
}

性能考虑

对于大量数据读写,应考虑使用缓冲和批量操作提高性能。

// 设置缓冲区
char buffer[8192];
FILE *file = fopen("largefile.bin", "rb");
if (file != NULL) {
    setvbuf(file, buffer, _IOFBF, sizeof(buffer));
    // 读取操作...
    fclose(file);
}

C++中可以通过以下方式提高性能:

ifstream bigFile("largefile.bin", ios::binary);
bigFile.rdbuf()->pubsetbuf(buffer, sizeof(buffer));

文件锁(跨进程同步)

在多进程环境中可能需要文件锁。

// 使用flock(Unix-like系统)
#include <sys/file.h>

int fd = open("file.txt", O_RDWR);
if (fd != -1) {
    if (flock(fd, LOCK_EX) == 0) {
        // 已获得锁...
        flock(fd, LOCK_UN);
    }
    close(fd);
}

Windows平台可使用LockFileEx:

HANDLE hFile = CreateFile("file.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
    OVERLAPPED ov = {0};
    if (LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, MAXDWORD, MAXDWORD, &ov)) {
        // 已获得锁...
        UnlockFileEx(hFile, 0, MAXDWORD, MAXDWORD, &ov);
    }
    CloseHandle(hFile);
}

 


网站公告

今日签到

点亮在社区的每一天
去签到