C/C++ File Operate

学了这么久的C/C ++ 说会也会 说不会也不会

我tm 居然不会文件操作 没事 上网 找几篇文章 学一下

文章在这

https://blog.csdn.net/afei__/article/details/81835684

https://blog.csdn.net/kingstar158/article/details/6859379

https://blog.csdn.net/houbincarson/article/details/136327765

我整理这几篇文件的内容并修改


C 语言文件操作

打开文件

FILE * fopen ( const char * filename, const char * mode );

参数

  • filename:文件名。

  • mode:打开模式。

模式

  • r:只读模式,文件必须存在。

  • r+:可读写模式,文件必须存在。

  • w:只写模式,文件不存在会创建,文件存在时会覆盖。

  • w+:可读写模式,文件不存在会创建,文件存在时会覆盖。

  • a:附加模式,打开只写文件。

  • a+:附加模式,打开可读写文件。

  • b:二进制模式(例如 "rb", "r+b", "wb")。

返回值

  • 成功返回文件指针,失败返回 NULL

关闭文件

int fclose ( FILE * stream );

返回值

  • 成功返回 0,失败返回 EOF-1

读文件

读取一个字符

int fgetc(FILE * stream);

返回值

  • 成功返回读取到的字符,遇到文件末尾返回 EOF

读取一个字符串

char * fgets ( char * str, int num, FILE * stream );
  • str:用于存储读取内容的目标字符串数组。

  • num:一次读取的大小。

检查文件末尾

int feof(FILE * stream);

返回值

  • 返回 0 表示未到文件末尾,返回 1 表示到达文件末尾。

写文件

写一个字符

int fputc ( int character, FILE * stream );

返回值

  • 成功返回写入的字符,失败返回 EOF

写一个字符串

int fputs ( const char * str, FILE * stream );

返回值

  • 成功返回正整数,失败返回 EOF

格式化输入输出

int fprintf ( FILE * stream, const char * format, ... );
int fscanf ( FILE * stream, const char * format, ... );
  • 用法与 sprintf 相同,输出到文件而非数组。

删除与重命名文件

重命名文件

int rename ( const char * oldname, const char * newname );

删除文件

int remove ( const char * filename );

返回值

  • 成功返回 0,失败返回其他值。


C++ 语言文件操作

包含头文件

#include <fstream> // 文件流操作
#include <iostream> // 输入输出流

文件流类型

  • ofstream:用于文件写操作。

  • ifstream:用于文件读操作。

  • fstream:用于读写操作。

C++ 写入文件

#include <iostream>
#include <fstream>
#include <thread>

using namespace std;

const char * FILENAME = "./test.txt";

int main() {
    // 创建文件流对象
    ofstream openfile;
    // 打开文件,如果文件不存在则创建
    openfile.open(FILENAME);
    // 写入内容
    openfile << "hello World" << endl;
    // 操作完成后关闭文件
    openfile.close();

    // 输出文件内容
    thread cat([]() { system("cat ./test.txt"); });
    cat.join();
    
    return 0;
}

注意

  • 每次运行时,open 会清空文件内容。

追加写入

openfile.open(FILENAME, ios::app);

C++ 读取文件

#include <iostream>
#include <fstream>
#include <thread>

using namespace std;

const string FILENAME = "./test.txt";

int main() {
    // 追加写入
    ofstream openfile;
    openfile.open(FILENAME, ios::app);
    openfile << "hello World" << endl;
    openfile.close();

    // 读取文件内容
    ifstream inputOnFile(FILENAME);
    if (inputOnFile.is_open()) {
        string fline;
        while (getline(inputOnFile, fline)) {
            cout << fline << endl;
        }
        inputOnFile.close();
    }
    
    return 0;
}

文件流状态检查

  • good():检查文件流状态是否良好。

  • fail():检查操作是否失败。

  • bad():检查流是否处于错误状态。

  • eof():检查是否到达文件末尾。

读取与写入的其他方法

  • get()put():逐字符读取和写入数据。

  • seekg()seekp():定位读写位置。

  • tellg()tellp():获取当前读写位置。

  • 运算符重载 operator<<operator>> 用于文件流的输出和输入操作。

流指针(Stream Pointers)

每个输入/输出流对象都有至少一个流指针:

  • ifstream:有一个称为 get pointer 的指针,指向下一个要读取的元素。

  • ofstream:有一个称为 put pointer 的指针,指向下一个要写入的元素。

  • fstream:同时包含 getput 指针。

获取和设置流指针

  • 获取流指针位置

    • tellg():返回当前 get pointer 的位置(输入流)。

    • tellp():返回当前 put pointer 的位置(输出流)。

  • 设置流指针位置

    • seekg(pos_type position):设置 get pointer 的位置为从文件开始计算的绝对位置。

    • seekp(pos_type position):设置 put pointer 的位置为从文件开始计算的绝对位置。

  • 带偏移的设置

    • seekg(off_type offset, seekdir direction):可以指定一个起始位置进行偏移。

    • seekp(off_type offset, seekdir direction):同上。

方向参数

  • ios::beg:从流开始位置计算的位移。

  • ios::cur:从当前流指针位置计算的位移。

  • ios::end:从流末尾处计算的位移。

Test

#include <iostream>
#include <fstream>

const char * filename = "test.txt";

int main() {
    long l, m;
    std::ifstream in(filename, std::ios::in | std::ios::binary);
    l = in.tellg();
    in.seekg(0, std::ios::end);
    m = in.tellg();
    in.close();
    std::cout << "size of " << filename << " is " << (m - l) << " bytes.\n";
    return 0;
}

[chen@RE fileTest_usecpp]$ make g++ -o main main.cc -std=c++11 [chen@RE fileTest_usecpp]$ ./main size of test.txt is 60 bytes. [chen@RE fileTest_usecpp]$ ls -la | grep test -rw-r--r-- 1 chen chen 60 11月 2日 18:05 test.txt [chen@RE fileTest_usecpp]$

缓冲区和同步(Buffers and Synchronization)

1. 缓冲区(Buffer)

  • 定义:缓冲区是一块内存空间,用于作为流(stream)和物理文件之间的媒介。

  • 作用:在文件流操作中,数据首先被写入或从缓冲区中读取,而不是直接与物理文件交互。

2. 缓冲区操作

  • 写操作:对于输出流,字符首先被插入到流的缓存中,而不是直接写入物理文件。

  • 读操作:对于输入流,数据从物理文件读取到缓存中,然后从缓存中读取。

3. 同步(Synchronization)

  • 定义:同步是指将缓冲区中的数据写入物理媒质或清除缓存的过程。

  • 触发条件:

    • 文件关闭:在文件关闭前,未完全写出或读取的缓存将被同步。

    • 缓存满:当缓存满时,会自动同步。

    • 控制符:遇到流中的特定控制符(如flush和endl)时,会触发同步。

    • 函数调用:调用成员函数sync()可以引发立即同步。

4. Linux缓冲区

  • fwrite函数:用于将数据从进程拷贝到缓冲区或外设中。

5. 缓冲区刷新策略

  • 立即刷新:无缓冲,数据直接写入物理媒质。

  • 行刷新:行缓存,常用于显示器。

  • 缓冲区满:

    • 全缓冲:当缓冲区满时,数据被写入物理媒质,常用于磁盘文件。

  • 特殊情况:

    • 用户强制刷新:用户可以通过调用函数或使用控制符来强制刷新缓冲区。

    • 进程退出:进程退出时,缓冲区会自动刷新。

6. 缓冲区的位置和类型

  • 位置:缓冲区位于高级语言层面,通过File*指针与file结构体关联,再通过fd与操作系统的文件描述符关联。

  • 类型:

    • stdout:标准输出流。

    • stdin:标准输入流。

    • stderr:标准错误流。

还有一些有用文档没整理

先放这

C/C++ 函数对比

https://developer.aliyun.com/article/1467851