第五章:标准I/O(2)--这后面的部分太难了。。。

实现细节

在标准I/O中,每一个标准I/O流都对应着一个与其相关联的文件描述符,我们可以调用以下函数来进行获得

#include 

int fileno(FILE *stream);
例子

我们写个程序简单看一下

#include 
using namespace std;

int main() {
    FILE* file_stream = fopen("07.txt", "r");
    if (!file_stream) {
        perror("fopen");
        return -1;
    }

    int fd = fileno(file_stream);
    if (-1 == fd) {
        perror("fileno");
        return -1;
    }

    printf("file descriptor: %d\n", fd);

    return 0;
}

结果:

应该返回文件描述符的值是3,结果是,符合预期

image-20230911103808954

我们这里再复习一下,标准错误默认是不带缓冲的,因为我们想要错误信息尽快显示到屏幕上,而不是关心是否具有换行符;标准输入和输出在连接到终端的时候默认是行缓冲的,如果定向到文件就是全缓冲

临时文件(了解)

tmpnam系列

有两个库函数可以用来帮助创建临时文件

#include 

char *tmpnam(char *s);
// tmpnam函数产生一个与现有文件名不同的一个有效路径名字符串,给的是路径名字
// 每次调用的时候都产生一个不同的路径名,最多的次数是TMP_MAX(238328)
// 现在tmpnam函数已经被弃用了,所以在使用的时候会报警告,但是能用,不推荐使用
// 在文件关闭或者程序结束的时候就自动删除这个临时文件

FILE *tmpfile(void);
// 用来创建一个二进制临时文件,同样在文件关闭或者程序结束的时候就自动删除这个临时文件
// UNIX对二进制文件不做区分
例子

我们先写一个关于tmpnam的例子

#include 
using namespace std;

int main() {
    char name[1024] = {0};

    // c++使用这个函数会被警告说不安全,tmpnam函数返回一个临时文件的路径名,这个路径名中对应的文件名和本文件不相同
    const char* tmp_path = tmpnam(name);
    if (!tmp_path) {
        perror("tmpnam");
        return -1;
    }

    cout << TMP_MAX << endl;

    cout << tmp_path << endl;
    cout << name << endl;

    return 0;
}

结果:

  • 在编译的时候,说这个函数不推荐,很危险
  • 输出结果可以看出TMP_MAX的值是238328,产生的有效路径字符串路径是/tmp/file6PoHsM,我们可以推测/tmp路径就是产生临时文件路径的,并且我传进去的name字符串数组也被赋值为了路径名,返回值也是这个,双重保险

第五章:标准I/O(2)--这后面的部分太难了。。。_第1张图片

我们来看下/tmp路径:

文件在程序结束之后就是释放掉了,确实是临时文件,做得很好

image-20230915150920192
mkdtemp系列

刚才使用tmpnam的时候编译器就提醒我们tmpnam函数不安全,建议使用mkdtemp函数

#include 

char *mkdtemp(char *template);
// 这个函数可以用来创建一个目录,这个目录有一个唯一的名字
// 这个名字是根据我传入的template路径指定的,我的template可以是一个绝对路径也可以是一个相对路径
// 但是为了保证名字唯一,必须要在这个字符串后面加上XXXXXX(6个)的路径名,系统会替换这六个字符让目录名字唯一

int mkstemp(char* template);
// 以唯一的名字创建一个普通文件并且打开文件,返回的值是文件描述符
// 成功,返回文件描述符;失败,返回-1

// 这两个函数创建的目录和文件都不会自动删除,如果想要删除我们必须要手动删除才可以!
例子

我们先试一下mkdtemp函数

#include 
using namespace std;

int main() {
    char name[1024] = {"./mydirXXXXXX"};

    char *file_path = mkdtemp(name);
    if (!file_path) {
        perror("mkdtemp");
        return -1;
    }

    cout << name << endl;
    cout << file_path << endl;

    return 0;
}

结果:

创建了一个目录,并且name字符串和函数的返回值都是这个路径,并且路径的位置也是正确的,当然我要选择绝对路径或者相对路径都是可以的

第五章:标准I/O(2)--这后面的部分太难了。。。_第2张图片

当然mkdtemp函数还有其他的作用:

image-20230915161221228

内存流(了解)

这部分看不懂思密达。。。

第五章:标准I/O(2)--这后面的部分太难了。。。_第3张图片 第五章:标准I/O(2)--这后面的部分太难了。。。_第4张图片 第五章:标准I/O(2)--这后面的部分太难了。。。_第5张图片

你可能感兴趣的:(《UNIX环境高级编程》,linux,c++)