Linux System Learning Note: file I/O

Source: Internet
Author: User

Linux supports standard I/O functions in the C language, and it also provides a set of SUS standard I/O library functions. Unlike standard I/O, Unix I/O functions are unbuffered, meaning that each read and write calls a system call in the kernel. This article summarizes Unix I/O and compares it to standard I/O.

File descriptor

The kernel references an open file through a file descriptor, which is a non-negative integer. By convention, the shell uses 0 associated with the standard input of the process, 1 is associated with the standard output, and 2 is associated with the standard error output. According to POSIX, these magic numbers should be replaced with symbolic constants Stdin_fileno , stdout_fileno ,Stderr_fileno to improve readability , defined in < The unistd.h> .

Linux Open file /dev/fd/n equivalent to the copy descriptor N, as well as/dev/stdin,/dev/stdout,/dev/steerr respectively equivalent to /dev/fd/0 , /dev/fd/ 1 , /dev/fd/2 .

fd = open ("/dev/fd/0", mode); Most systems ignore the mode specified by this function call, while others require mode to be a subset of the open mode used when the referenced file (here is the standard input) is initially opened. Since the above open is equivalent to FD = DUP (0) , then descriptor 0 and FD share the same file table entry. It is because the same file table entries are shared that they see the file status flags (that is, open mode ) should be the same.

UNIX-standard I/O functions

The UNIX standard set of I/O functions mainly includes open , creat , close , lseek , read , writ E .

Opening files with open and creat

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>/* Open or create a file * @return      successfully Returns a file descriptor, Error returned-1 */int open (const char *pathname, int flags), int open (const char *pathname, int flags, mode_t mode);/* Create file * @retur N      successfully returned as a write-only open file descriptor, error returned-1 */int creat (const char *pathname, mode_t mode);

Parameter description:

Pathname
The
name of the file to open or create.
Flags

function options, including:

    • o_rdonly , read-only open.
    • o_wronly , write-only open.
    • O_rdwr , read and write open.

The above three options must be there and only one. The optional options are:

    • o_append , each write is appended to the end of the file.
    • o_creat , creating a file when the file does not exist, you need to set the mode parameter.
    • o_excl , with o_creat , file already exists error, file does not exist then create file, make test and create an atomic operation.
    • O_trunc , the length truncation is 0 when the file exists and is open for writing.
    • O_noctty , for terminal equipment, the device is not assigned to the control terminal of this process.
    • O_nonblock , for FIFO, block special files, character special files, set to non-blocking mode.

There are also three synchronization-related options:

    • o_sync , write waits for the physical I/O operation to complete, including updates to the file properties.
    • O_dsync , write waits for the physical I/O operation to complete, and if the write does not affect the read (such as the file size does not change), do not wait for the file attributes to be updated
    • o_rsync , a synonym for o_sync .

The file descriptor returned by Open must be the smallest available descriptor, sometimes with this feature to open the file on the standard input/output/error output.

creat is a historical legacy function for cases where there is no previous o_creat option, which is equivalent to:

Open (Pathname, o_wronly| O_creat| O_trunc, mode);

Close a file using close

#include <unistd.h>/* Close Open file * @return      successfully returned 0, error returned-1 */int close (int fd);

Closing a file frees all record locks that the process adds to the file. When the process terminates, the kernel automatically closes its open file.

An open file has an associated current file offset, usually a non-negative integer, that represents the number of bytes from the beginning of the file. The read/write operation starts at the current file offset, increasing the number of bytes read and written by the offset. The default open file offset is 0 to o_append Open the offset to the number of bytes of the file. You can set the offset of the file with Lseek .

Lseek Gets or sets the offset of the file

#include <sys/types.h> #include The offset of the <unistd.h>/* settings file, set to whence the specified location plus offset * @return A      successful return of the new file offset, Error returned-1 */off_t lseek (int fd, off_t offset, int whence);

Parameter description:

Offset
The offset to increase.
Whence
  • Seek_set , relative to the beginning of the file.
  • seek_cur , relative to the current location of the file.
  • seek_end , relative to the end of the file.

The Lseek does not cause I/O operations and the offsets are recorded in the kernel.

The offset of the normal file must be a non-negative integer. The offset can be greater than the length of the file, so that subsequent writes form an empty hole that does not occupy the storage, where the bytes are read as 0. You can write a file like this, verify it with the od- C command, and use the ls -ls command to view the disk block usage.

Read the file's data with the read function

#include <unistd.h>/* reads data from an open file, starts at the current offset, and increments the offset by the actual number of bytes read * @return The      number of bytes read successfully returned to the end of the file returned 0, error returned-1 */ssize_t Read (int fd, void *buf, size_t count);

Due to the size of the file, network buffers, pipelines, the actual number of bytes in the FIFO limit, the actual read data may be less than the number of bytes to read, signal interruption will also cause this situation. End devices usually read one line at a time, and a record is read by a device such as a tape.

Write data to a file using the write function

#include <unistd.h>/* writes data to an open file, starting at the current offset, and increasing the offset by the actual number of bytes written * @return The      number of bytes written successfully returned, error returned-1 */ssize_t write (int fd, const void *buf, size_t count);

For normal files, the write operation starts at the current offset of the file. If the O_append option is specified when the file is opened, the offset of the file is set at the current end of the file before each write operation.

#include <stdlib.h> #include <unistd.h> #include "error.h" #define Buffsize    4096int main (void) {    int     N;    Char    buf[buffsize];    while ((n = Read (Stdin_fileno, buf, buffsize)) > 0)        if (write (Stdout_fileno, buf, n)! = N)            err_sys ("Write error ");    if (n < 0)        Err_sys ("read error");    Exit (0);}

Note the effect of different buffer lengths on Linux on the time of the read operation.

File sharing

UNIX supports different processes to share open files. The kernel uses three types of data structures to represent open files:

    • Open File Descriptor table: The process has a record entry in the process table that contains a list of open file descriptors. Each descriptor occupies an item that contains a descriptor flag and a pointer to a file table entry.
    • File Table : The kernel maintains a file table of all open files, each of which contains a file status flag, the current file offset, and a pointer to the File V node table entry.
    • v-junction table : Each open file has a V-node table, and each v node contains the file type, the operation function pointer, and the I node of the file.

Linux implements the V node and the I node as an I node independent of the file system and the I node that relies on the file system.

when different processes share files, each process has a file table entry for that file, pointing to the same v-node table. Multiple file descriptors may also point to the same file table entry, such as using the DUP function and the parent-child process after fork .

Note: File table entries to be stored in the kernel, open file descriptor tables can be stored in user space (as a separate structure corresponding to each process, can be swapped out), rather than in the process table. These tables can also be implemented in a number of ways, not necessarily arrays, for example, they can be implemented as a linked list of structures.

Atomic operation

Linux System Learning Note: file I/O

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.