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);
}