Unix programming learning notes (2) -- I/O without buffering

Source: Internet
Author: User

Lien000034
2014-08-25

1. file descriptor

For the kernel, all opened files are referenced through the file descriptor. The file descriptor is a non-negative integer. When an existing file is opened or a new file is created, the kernel returns a file descriptor to the process. When reading or writing a file, use the file descriptor returned by open or creat to identify the file and send it as a parameter to read or write.

By convention, the UNIX System Shell Associates file descriptor 0 with the standard input of the process, and file descriptor 1 with the standard output of the process, file descriptor 2 is associated with the standard error output of the process.

2. I/O functions without buffering

The term "no buffer" means that each read or write calls a system call in the kernel. These unbuffered I/O functions are not components of Iso c, but they are components of posix.1 and single UNIX specification. The following describes five basic functions: open, read, write, lseek, and close.

2.1 Open Functions

You can call the OPEN function to open or create a file.

# Include <fcntl. h>
Int open (const char * pathname, int Oflag,.../* mode_t mode */);
Returned value: If successful, the system returns the file descriptor. If an error occurs, the system returns-1.

The third parameter... indicates that the number and type of the remaining parameters vary depending on the specific call. For Open functions, the third parameter is used only when a new file is created. Pathname is the name of the file to be opened or created. The Oflag parameter is used to describe multiple options of this function. Use one or more of the following constants to perform the "or" operation to form the Oflag parameter (these constants are defined in the <fcntl. h> header file ).

O_rdonly read-only

O_wronly write-only open

O_rdwr read and write open

One of the three constants must be specified and only one can be specified. The following constants are optional:

O_append is appended to the end of the file each time it is written.

O_creat: if the file does not exist, create it. When this option is used, the third parameter mode is required to specify the access limit for the new file.

If o_excl is specified at the same time and the file already exists, an error occurs. This can be used to test whether a file exists. If it does not exist, the file is created.

O_trunc if this file exists, and to write only or read and write successfully open, its length is truncated to 0.

O_noctty if pathname refers to a terminal device, the device is not assigned a control terminal for this process.

If o_nonblock refers to a FIFO, a block special file, or a special character file, this option sets the non-blocking mode for local file opening and subsequent I/O operations.

Example 1:

The following program opens the file foo.txt in read-only mode and sets the o_creat and o_excl options of the open function.

#include <fcntl.h>#include <stdlib.h>#include <stdio.h>intmain(void){    int fd;    if ((fd = open("foo.txt", O_RDONLY | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR | S_IRGRP)) == -1) {        printf("open error\n");    } else {        printf("open success\n");    }    exit(0);}

Compile the program, generate open_demo, and execute it. The result is as follows:

Lien000034: Demo $ gcc-O open_demo open_demo.clien000034: Demo $ lsopen_demoopen_demo.clien000034: Demo $. /open_demoopen successlien000034: Demo $ LS-l foo.txt-RW-r ----- 1 lien000034 lien000034 August 19 22:56 foo.txt lien000034: Demo $. /open_demoopen Error

When the o_creat option is specified, the third parameter takes the "or" operation result of these constants in the list below to specify the access permission for the new file (these constants are defined in <sys/STAT. h> medium ).

Table. File Access Permissions
S_irusr User-read
S_iwusr User-write
S_ixusr User-execution
S_irgrp Group-read
S_iwgrp Group-write
S_ixgrp Group-execution
S_iroth Others-read
S_iwoth Others-write
S_ixoth Others-execution


 
 
 
 
 
 
 
 

 

 

The file descriptor returned by open must be the smallest unused descriptor value. This can be used to open a new file on the standard input, standard output, or standard error output.

The Oflag parameter of the open function also supports three optional constants, which are part of the synchronous Input and Output options in single unixspecification.

O_dsync enables each write operation to wait for the completion of the physical I/O operation. However, if the write operation does not affect reading the data just written, the file attribute is not updated.

O_rsync waits for each read operation with the file descriptor as the parameter until any pending write operation on the same part of the file is completed.

O_sync makes every write wait for the completion of the physical I/O operation, including the I/o Required for updating the file attributes caused by the write operation.

When a file is opened with the o_dsync flag, the time attribute of the file is not updated synchronously when the existing content is overwritten. In contrast, if the file is opened with the o_sync mark, every write operation on the file will update the file time before the write return.

2.2 creat Function

You can call the creat function to create a new file.

# Include <fcntl. h>

Int creat (const char * pathname, mode_t mode );

Returned value: if the operation is successful, the system returns the file descriptor that is opened only. If an error occurs, the system returns-1.

This function is equivalent:

Open (pathname, o_wronly | o_creat | o_trunc, mode );

One disadvantage of the creat function is that it opens the created file in write-only mode. The creat function exists because in early Unix systems, the second parameter of the open function can only be 0, 1, or 2. There is no way to open an existing file, so the creat function is required to create a new file. After the OPEN function supports the o_creat option, the creat function is unnecessary.

2.3 close Function

Call the close function to close an opened file.

# Include <unistd. h>

Int close (INT filedes );

Returned value: 0 is returned if the request is successful, and-1 is returned if an error occurs.

When a process is terminated, the kernel automatically closes all open files.

2.4 READ function

Call the READ function to read data from open files.

# Include <unistd. h>

Ssize_t read (INT filedes, void * Buf, size_t nbytes );

Return Value: if the result is successful, the number of bytes read is returned. If the result is reached the end of the file, 0 is returned. If an error occurs,-1 is returned.

The read operation starts from the current offset of the file. Before the result is returned, the offset increases the number of bytes actually read.

2.5 write function

Call the write function to open the file to write data.

# Include <unistd. h>

Ssize_t write (INT filedes, const void * Buf, size_t nbytes );

Returned value: if the operation succeeds, the number of written bytes is returned. If an error occurs, the value-1 is returned.

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 file offset is set at the current end of the file before each write operation. After a successful write, the offset of the file increases the number of actually written bytes.

2.6 lseek Functions

Call lseek to display the offset of an opened file.

# Include <unistd. h>

Off_t lseek (INT filedes, off_t offset, int whence );

Return Value: if the operation succeeds, the new file offset is returned. If an error occurs, the value-1 is returned.

Each opened file has an associated "current file offset ". It is usually a non-negative integer used to measure the number of bytes calculated from the beginning of the file. By default, when a file is opened, the offset is set to 0 unless the o_append option is specified.

The interpretation of the offset parameter of the lseek function is related to the value of the whence parameter.

• If whence is seek_set, set the offset of the file to the offset byte from the start of the file.

• If whence is seek_cur, set the offset of the file to its current value plus offset, which can be positive or negative.

• If the whence is seek_end, set the offset of the file to the offset of the file length. The offset can be positive or negative.

The offset cannot be set for pipelines, FIFO, and network sockets. If a file descriptor references one of the three, the lseek function returns-1 and errno is set to espipe. For normal files, the offset can only be non-negative. However, some settings may support a negative offset. Therefore, be cautious when comparing the return values of the lseek function. Do not test whether it is less than 0, but test whether it is equal to-1.

The file offset can be greater than the current length of the file. In this case, the next write to the file will lengthen the file and create a hole in the file. Bytes in the file but not written are read as 0.

Instance:

The following program creates a new file. hole: first write "ABCD" at the beginning of the file, then move the file offset to 10 bytes from the start, and write "ABCD" at the beginning, then in the file. hole forms a hole between 4th bytes and 9th bytes.

#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>char buf1[] = "abcd";char buf2[] = "ABCD";intmain(void){    int fd;    if ((fd = open("file.hole", O_WRONLY | O_CREAT | O_TRUNC,S_IRUSR | S_IWUSR | S_IRGRP)) < 0) {        printf("open error");    }    if (write(fd, buf1, 4) != 4) {        printf("write buf1 error");    }    if (lseek(fd, 10, SEEK_SET) == -1) {        printf("lseek error");    }    if (write(fd, buf2, 4) != 4) {        printf("write buf2 error");    }    exit(0);}


Compile the program, generate the writedemo file, and then execute the writedemo file,

Lien000034: Demo $ gcc-O writedemo write_demo.clien000034: Demo $. /writedemolien000034: Demo $ LS-l file. hole-RW-r ----- 1 lien000034 lien000034 14 August 20 21:37 file. holelien000034: Demo $ OD-C file. hole0000000 a B c d \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 a B C d000001

Unix programming learning notes (2) -- I/O without buffering

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.