文章目录
1. C语言
在C语言中,文件访问是通过一系列标准库函数来完成的,这些函数被定义在stdio.h(标准输入输出库)头文件中。
 文件的访问主要通过以下几个函数实现:
| 函数 | 说明 | 
|---|---|
| fopen() | 打开一个文件 | 
| fclose() | 关闭一个文件 | 
| fread() | 读取文件 | 
| fwrite() | 写入文件 | 
| fseek() | 移动文件指针到指定位置 | 
| ftell() | 获取文件指针当前位置 | 
| fgetc() | 从文件中读取一个字符 | 
| fputc() | 写入一个字符到文件中 | 
- Note:通过文件指针来实现文件的访问。
 
-  
打开文件:
FILE *fopen(const char *filename, const char *mode);
此函数打开一个文件并返回一个文件指针,该文件指针可用于后续的文件操作。如果文件无法打开,则返回NULL。- filename 是文件名(可以包含路径)。
 - mode 是打开文件的模式,例如 “r”(只读)、“w”(只写,创建新文件或覆盖旧文件)、“a”(追加,写入数据到文件末尾)、“r+”(读写)等。
 
 -  
关闭文件:
int fclose(FILE *stream);
此函数关闭一个打开的文件。如果成功关闭文件,则返回0;否则返回EOF(一个定义在stdio.h中的特殊值,表示文件结束或发生错误)。 -  
读取文件:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
此函数从文件中读取数据。函数返回实际读取的数据项的数量,如果发生错误或到达文件末尾,则可能小于count。- ptr 是一个指向内存块的指针,该内存块用于存储从文件中读取的数据。
 - size 是每个数据项的大小(以字节为单位)。
 - count 是要读取的数据项的数量。
 - stream 是文件指针。
 
 -  
写入文件:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
此函数将数据写入文件。函数返回实际写入的数据项的数量,如果发生错误,则可能小于count。- ptr 是一个指向要写入文件的数据的指针。
 - size、count 和 stream 的含义与fread相同。
 
 -  
文件定位:
int fseek(FILE *stream, long offset, int whence);
此函数设置文件位置指针。如果成功,则返回0;否则返回非零值。- offset 是相对于whence指定的位置的偏移量(以字节为单位)。
 - whence 可以是 SEEK_SET(文件开头)、SEEK_CUR(当前位置)或 SEEK_END(文件末尾)。
 
 -  
获取当前位置:
long ftell(FILE *stream);
此函数返回文件位置指针的当前位置(以字节为单位)。如果发生错误,则返回-1L。 -  
检查文件结束:
int feof(FILE *stream);
此函数检查文件是否已到达末尾。如果到达末尾,则返回非零值;否则返回0。 -  
清除文件结束和错误标志:
void clearerr(FILE *stream);
此函数清除与stream关联的文件结束和错误标志。 -  
检查文件错误:
int ferror(FILE *stream);
此函数检查与stream关联的文件是否发生错误。如果发生错误,则返回非零值;否则返回0。 -  
格式化输出或输入:
int fscanf(FILE *fp, char *format, …);
int fprintf(FILE *fp, char *format, …); -  
行输入和输出
char *fgets(char *line, int maxline, FILE *fp);
int fputs(char *line, FILE *fp); 
1.1 打开并读取文件
#include <stdio.h>
#include <stdlib.h>
 
int main() {
    FILE *file = fopen("test.txt", "r");
    if (file == NULL) {
        printf("无法打开文件\n");
        return -1;
    }
 
    char ch;
    while ((ch = fgetc(file)) != EOF) {
        printf("%c", ch);
    }
 
    fclose(file);
    return 0;
}
 
1.2 写入文件
#include <stdio.h>
#include <stdlib.h>
 
int main() {
    FILE *file = fopen("test.txt", "w");
    if (file == NULL) {
        printf("无法打开文件\n");
        return -1;
    }
 
    fputc('A', file);
    fputc('B', file);
 
    fclose(file);
    return 0;
}
 
1.3 读取二进制文件
#include <stdio.h>
#include <stdlib.h>
 
typedef struct {
    int a;
    char b;
} Data;
 
int main() {
    FILE *file = fopen("test.bin", "rb");
    if (file == NULL) {
        printf("无法打开文件\n");
        return -1;
    }
 
    Data data;
    fread(&data, sizeof(Data), 1, file);
 
    printf("a: %d, b: %c\n", data.a, data.b);
 
    fclose(file);
    return 0;
}
 
1.4 写入二进制文件
#include <stdio.h>
#include <stdlib.h>
 
typedef struct {
    int a;
    char b;
} Data;
 
int main() {
    FILE *file = fopen("test.bin", "wb");
    if (file == NULL) {
        printf("无法打开文件\n");
        return -1;
    }
 
    Data data = {1, 'A'};
    fwrite(&data, sizeof(Data), 1, file);
 
    fclose(file);
    return 0;
}
 
1.5 文件指针的移动
#include <stdio.h>
#include <stdlib.h>
 
int main() {
    FILE *file = fopen("test.txt", "r");
    if (file == NULL) {
        printf("无法打开文件\n");
        return -1;
    }
 
    fseek(file, 2, SEEK_SET); // 将文件指针移动到第3个字符的位置
    printf("%c\n", fgetc(file));
 
    fclose(file);
    return 0;
}
 
2. C++
在C++中,文件访问与C语言非常相似,因为C++是在C语言的基础上构建的,并保留了C语言的大部分I/O功能。C++使用相同的文件操作函数,这些函数在(或<stdio.h>)头文件中定义。然而,C++还提供了自己的文件流类(如std::ifstream、std::ofstream和std::fstream),这些类位于头文件中,提供了更加面向对象的文件操作方式。
2.1 包含头文件
#include <fstream>
 
2.2 打开文件
使用 std::ifstream(输入文件流)或 std::ofstream(输出文件流)来打开文件。例如:
std::ifstream inputFile("input.txt"); // 打开文件以进行读取
std::ofstream outputFile("output.txt"); // 打开文件以进行写入
 
可以使用 std::fstream(文件流)来同时读取和写入文件。
2.3 检查文件是否成功打开
可以通过检查文件流对象是否有效来确认文件是否成功打开。
if (!inputFile) {
    std::cerr << "无法打开文件\n";
    return 1;
}
 
2.4 读取文件
使用 >> 运算符或 getline() 函数来从文件中读取数据。
int number;
inputFile >> number; // 读取一个整数
std::string line;
std::getline(inputFile, line); // 读取一行文本
 
2.5 写入文件
使用 << 运算符来将数据写入文件。
outputFile << "Hello, World!\n"; // 写入一行文本
outputFile << 42; // 写入一个整数
 
2.6 关闭文件
当文件流对象超出范围或被销毁时,文件会自动关闭。但是,你也可以显式地调用 close() 方法来关闭文件。
outputFile.close();
 
2.7 文件指针的移动和获取位置
使用 seekg()(对于输入流)和 seekp()(对于输出流)来移动文件指针。使用 tellg()(对于输入流)和 tellp()(对于输出流)来获取当前文件指针的位置。
inputFile.seekg(10, std::ios::beg); // 将输入文件的指针移动到第10个字节
std::streampos pos = inputFile.tellg(); // 获取当前输入文件的指针位置
 
2.8 实例
//读取文件
#include <fstream>
#include <iostream>
#include <string>
int main() {
    std::ifstream file("test.txt"); // 打开文件以供读取
    if (!file) { // 检查文件是否成功打开
        std::cerr << "无法打开文件\n";
        return 1;
    }
    std::string line;
    // 逐行读取文件
    while (std::getline(file, line)) {
        std::cout << line << '\n';
    }
    file.close(); // 关闭文件
    return 0;
}
 
//写入文件
#include <fstream>
#include <iostream>
int main() {
    std::ofstream file("test.txt"); // 打开文件以供写入(如果文件不存在,则创建它)
    if (!file) { // 检查文件是否成功打开
        std::cerr << "无法打开文件\n";
        return 1;
    }
    file << "Hello, World!" << std::endl; // 写入数据到文件
    file.close(); // 关闭文件
    return 0;
}
 
C++的文件流类同样支持二进制文件的读写。你可以通过文件流的binary模式标志来指定文件应以二进制模式打开。但是,在大多数系统中,这并不是必须的,因为文件流默认就是二进制安全的。然而,在某些情况下(特别是跨平台操作时),明确指定二进制模式可能是有必要的。
std::ifstream file("test.bin", std::ios::binary); // 以二进制模式打开文件
// ... 读取操作 ...
std::ofstream file("test.bin", std::ios::binary); // 以二进制模式打开文件
// ... 写入操作 ...
 
note:使用文件流类进行文件操作通常比使用C风格的函数更加直观和易于管理,因为它们提供了更丰富的错误处理和更面向对象的接口。此外,文件流还支持更多的操作,如格式化输入/输出、操纵符重载等.
3. C语言和C++文件打开模式
C++和C语言在文件打开模式上有很多相似之处,但由于C++提供了更高级的封装,其使用方式略有不同。以下是一个简化的表格,列出了C++和C语言中常用的文件打开模式:
| 模式 | 描述 | C++示例 | C示例 | 
|---|---|---|---|
| “r” | 以只读方式打开文件,文件必须存在 | std::ifstream file(“test.txt”, std::ios::in); | FILE *file = fopen(“test.txt”, “r”); | 
| “w” | 以写入方式打开文件,如果文件不存在则创建新文件,如果文件已存在则清空内容 | std::ofstream file(“test.txt”, std::ios::out); | FILE *file = fopen(“test.txt”, “w”); | 
| “a” | 以追加方式打开文件,如果文件不存在则创建新文件,如果文件已存在则在文件末尾追加内容 | std::ofstream file(“test.txt”, std::ios::out/std::ios::app); | FILE *file = fopen(“test.txt”, “a”); | 
| “r+” | 以读写方式打开文件,文件必须存在 | std::fstream file(“test.txt”, std::ios::in/std::ios::out); | FILE *file = fopen(“test.txt”, “r+”); | 
| “w+” | 以写读方式打开文件,如果文件不存在则创建新文件,如果文件已存在则清空内容 | std::fstream file(“test.txt”, std::ios::in/std::ios::out/std::ios::trunc | FILE *file = fopen(“test.txt”, “w+”); | 
| “a+” | 以追加写读方式打开文件,如果文件不存在则创建新文件,如果文件已存在则在文件末尾追加内容 | std::fstream file(“test.txt”, std::ios::in /std::ios::out) | |
| “b” | 以二进制模式打开文件(可以与上述模式组合使用) | std::ifstream file(“test.bin”, std::ios::in/std::ios::binary); | 
4. MFC
在MFC(Microsoft Foundation Classes)中,CFile 类是一个用于文件操作的封装类,它提供了比标准C语言I/O函数更高级和面向对象的接口。使用 CFile 类,你可以更方便地打开、读取、写入和关闭文件。
4.1 头文件
#include <afxwin.h> // MFC 头文件
#include <afx.h>    // 包含CFile类的定义
 
4.2 打开文件
CFile file(_T("example.txt"), CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive);
if (!file.Open()) {
    AfxMessageBox(_T("无法打开文件"));
    return;
}
 
试图以创建(如果不存在)、写入和独占模式打开一个名为 example.txt 的文件。如果文件打开失败,显示一个消息框。
4.3 写入文件
CString str = _T("Hello, World!");
ULONGLONG pos = file.GetPosition(); // 获取当前文件指针位置
file.Write(str, (UINT)str.GetLength() * sizeof(TCHAR)); // 写入字符串到文件
file.Seek(pos, CFile::begin); // 如果需要,可以将文件指针移回原位
 
将一个字符串写入文件。Write 函数需要两个参数:要写入的数据的指针和要写入的数据的大小(以字节为单位)。
4.4 读取文件
ULONGLONG len = file.GetLength(); // 获取文件长度
if (len > 0) {
    CFileException e;
    char* buffer = new char[len];
    try {
        file.Read(buffer, len); // 读取整个文件
    }
    catch (CFileException* pEx) {
        e = *pEx;
        pEx->Delete();
        // 处理异常
    }
    // 使用 buffer 中的数据...
    delete[] buffer; // 释放内存
}
 
在这个例子中,我们首先获取文件的长度,然后分配足够的内存来存储整个文件的内容。我们使用 Read 函数来读取文件内容。注意,我们使用 CFileException 来处理可能发生的异常。
4.5 关闭文件
file.Close(); // 关闭文件
 
在完成文件操作后,使用 Close 函数关闭文件。虽然 CFile 的析构函数会自动关闭文件(如果尚未关闭),但显式关闭文件是一个好习惯。
MFC 主要用于Windows桌面应用程序的开发,并且依赖于Microsoft的Visual C++环境。如果你正在开发跨平台应用程序或不想依赖MFC,那么使用标准C++的 库可能是更好的选择。










