Standard IO_open and close files_fopen, fdopen, freopen, stdin, stdout, stderr

Directory

1. Open the file

1.1 fopen function prototype

1.1.1 fopen function

1.1.2 Principle of fopen function

1.1.3 What is the difference between text files and binary files?

1.1.4 What is the difference between “r” mode and “rb” mode?

1.1.5 Example of using fopen function

1.2 fdopen function prototype

1.2.1 fdopen function

1.2.2 Principle of fdopen function

1.2.3 Example of using fdopen function

1.3 freopen function prototype

1.3.1 The freopen function

1.3.2 Principle of freopen function

1.3.3 Example of using freopen function

2. Close the file

2.1 fclose function prototype

2.1.1 fclose function

3. Introduction to stdin, stdout, stderr


1. Open the file

1.1 fopen function prototype

1.1.1 fopen function

#include <stdio.h>

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

Function introduction: The fopen function is a function in the C language standard library, which is used to open a file and return a file pointer.

Function parameters:

pathname: String, indicating the file name to open.

mode: string, indicating the mode of opening the file, the specific setting method refers to Table 1-1

Table 1-1 fopen function mode parameter reference table

Function return value:

Success: Returns the file pointer.

Failure: returns NULL with errno set.

1.1.2 Principle of fopen function

Figure 1-1 Principle of fopen function

After calling the fopen function, a FILE object will be created in the user space, and at the same time, a sturct file object and a struct inode object will be created in the kernel through the open system call. The principle of the open system call refers to: File IO_Open and close files (attached to Linux-5.15.10 Kernel source code analysis)

After calling open successfully, a fd (file descriptor) will be returned, and the _fileno member of the FILE object will record the fd. _fileno is a bridge for data interaction between user space and kernel space.

You can use _fileno and the file IO system call to directly interact with the kernel, or you can interact with the kernel through the FILE file pointer and the standard IO interface.

1.1.3 What is the difference between text files andbinary files?

Figure 1-2 Text and binary files

Text files and binary files are the same in the storage layer and are stored in binary form.

The difference lies in the logic layer. Text files are usually files that conform to certain coding standards (such as ASCII codes). When operating text files, our input and output data must conform to the coding standards. This is an artificial regulation. If it does not meet the coding standards There will be garbled characters and so on.

Binary files are standardized by value encoding, and the input and output data are in the form of numbers (such as hexadecimal). Reading and writing files in binary mode is usually not easy to make mistakes, because what you see is what you get, and there is no conversion link in the middle.

1.1.4 Difference between “r” mode and “rb” mode?

, “r” mode: Open the file in text mode for reading. In text mode, newlines in the file are converted to newlines (\
), which may vary on different operating systems (for example, newlines on Windows are \r\
). This mode is suitable for reading text files, such as plain text files, CSV files, etc.

“rb” mode: Open the file for reading in binary mode. In binary mode, the data in the file is read as bytes without any conversion. This mode is suitable for reading binary files, such as pictures, audio, video, etc.

1.1.5 Example of using fopen function

#define TEST_FILE "/tmp/test.txt"

int fopen_test() {
    FILE *fp = fopen(TEST_FILE, "r + ");
    if (!fp) {
        perror("fopen error");
        return -1;
    }

    fclose(fp);
    return 0;
}

1.2 fdopen function prototype

1.2.1 fdopen function

#include <stdio.h>

FILE *fdopen(int fd, const char *mode);

Function introduction: The fdopen function is one of the standard library functions used to convert a file descriptor (file descriptor) into a file pointer (FILE*) in C language.

Function parameters:

fd: Integer, indicating the file descriptor to be converted.

mode: Refer to the fopen function mode parameter.

Function return value:

Success: Returns the file pointer.

Failure: returns NULL with errno set.

1.2.2 fdopen function principle

Figure 1-3 Principle of fdopen function

From the principle of the fopen function, we know that there are two ways to exchange data between user space and kernel space:

  • Interact directly with the kernel through _fileno and file IO system calls.
  • Interact with the kernel through FILE file pointers and standard IO interfaces.

The main function of the fdopen function is to open a FILE file pointer after the file descriptor opened by the open function, so that the FILE file pointer can interact with the kernel through the standard IO interface.

1.2.3 Example of using fdopen function

int fdopen_test() {
    FILE *fp = fdopen(1, "w");
    if (!fp) {
        perror("freopen error");
        return -1;
    }

#define TEST_STRING "helloworld\
"
    fwrite(TEST_STRING, strlen(TEST_STRING), 1, fp);

    printf("let`s go\
");
    fclose(fp);
    return 0;
}

1.3 freopen function prototype

1.3.1 freopen function

#include <stdio.h>

FILE *freopen(const char *pathname, const char *mode, FILE *stream);

Function introduction: The freopen function is one of the standard library functions used to redirect file streams in C language.

Function parameters:

pathname: String representing the filename to redirect to.

mode: Refer to the fopen function mode parameter.

stream: The opened file stream pointer, indicating the file stream to be redirected.

Function return value:

Success: Returns the file pointer.

Failure: returns NULL with errno set.

1.3.2 Principle of freopen function

Figure 1-4 Principle of freopen function 1

Figure 1-5 Principle 2 of freopen function

The freopen function is mainly used for file redirection.

Before calling the freopen function, we have opened a file through the fopen function and returned the FILE file pointer, or the file pointer opened by default such as: stdin, stdout, stderr. The opened file will create struct file and struct inode objects in the kernel.

When the freopen function is called, the kernel struct file and struct inode corresponding to the original FILE file pointer will be replaced by the new struct file object and struct inode object, and the original object will be closed. At this time, when we operate the FILE file pointer, we operate Is the new struct file object and struct inode object.

The interior of freopen is actually implemented through the dup3 system call. For the principle of the dup3 system call, please refer to: file IO_copy file descriptor (with Linux-5.15.10 kernel source code analysis)

1.3.3 Example of using freopen function

int freopen_test() {
    FILE *fp = freopen("test.log", "w", stdout);
    if (!fp) {
        perr string-literal r");
        return
    } Type: char[12]
             Size: 12 bytes
    printf("_fileno:%d\
", fp->_fileno);
    fclose(fp);
    return 0;
}

2. Close the file

2.1 fclose function prototype

2.1.1 fclose function

#include <stdio.h>

int fclose(FILE *stream);

Function introduction: The fclose function is a function in the C language standard library, which is used to close the file associated with the file pointer.

Function parameters:

stream: The file pointer to close.

Function return value:

Success: returns 0.

Failure: returns EOF (-1).

The fclose function does the following:

  • Flush the contents of the buffer to disk.
  • Close the file descriptor.
  • Release resources associated with the file.

Notes:

  • After using the file pointer, you should use the fclose function to close the file in time to avoid resource leaks.
  • Before closing the file, make sure the file pointer is valid, that is, not NULL.
  • After closing a file, do not use a closed file pointer for file operations, or undefined behavior will result.

3.stdin, stdout, stderr introduction

Figure 3-1 Principles of stdin, stdout, stderr

Linux systems use three standard streams to process data: stdin (standard input), stdout (standard output), and stderr (standard error).

The Linux system will open stdin, stdout, stderr FILE file pointers by default, and there is no need for user programs to actively open them.

There is no difference between stdin, stdout, stderr and ordinary FILE, the main difference is that the file types corresponding to the struct inode in the kernel space are different.

  • Standard input (stdin)

Standard input is usually represented as file descriptor 0. It is used to receive input data. In the command line environment, it is bound to the keyboard by default and is used to read user input from the keyboard. In a program, you can use stdin to read data entered by the user.

  • Standard output (stdout)

Standard output is usually represented as file descriptor 1. It is used to output the results or information of a program. In the command line environment, it is bound to the terminal by default and displays the results or information on the screen. In a program, you can use stdout to output results or information.

  • Standard error (stderr)

Standard error is usually represented as file descriptor 2. It is used to output program error messages, warnings or debugging information. Unlike standard output, standard error is dedicated to outputting error messages related to program execution. In the command line environment, it is also bound to the terminal by default to display error messages on the screen. In programs, you can use stderr to output error messages.