1 Introduction
I/O (unbuffered I/O) without a buffer refers to a system call in the kernel called by each read or write, these I/O without a buffer are not components of Iso c.
2. file descriptor
Each opened file is referenced by a file descriptor, which is a non-negative integer. The file descriptor returned by the open and create functions is used by read write and close.
In UNIX, file descriptor 0 is associated with standard input, file descriptor 1 is associated with standard output, and file descriptor 2 is associated with standard error output.
3. I/O functions without a buffer
The following describes six common I/O functions: open, creat, read, write, lseek, and close.
3.1 open Functions
# Include <fcntl. h> int open (const char * pathname, int Oflag,.../* mode_t mode */): The file descriptor is returned successfully, and-1 is returned when an error occurs.
The file descriptor returned by the open function must be the smallest unused descriptor value.
For open, the third parameter mode is used only when a new file is created.
Pathname is the name of the open or create file. Oflag indicates the option of this function. The following constants are bitwise OR constitute Oflag (these constants are defined in <fcntl. h>)
Required: You can select only one
O_rdonly read-only
O_wronly write-only open
O_rdwr read/write Enabled
Optional:
Every write operation on o_append is written at the end of the file.
O_creat: if this file does not exist, create it. When using this option, you must specify the third parameter mode to specifyAccess bit permission.
If o_excl is specified at the same time, if this file exists, an error is returned.-1 is used to test whether a file exists.Atomic operation
O_trunc if the file exists, and the file is truncated to 0 if it is only written or read/write successfully opened.
O_noctty if pathname is a terminal device, the device is not allocated as the control terminal of the process.
O_nonblock if pathname is a FIFO, a block Special Envoy file, and a special character file, this option is set to non-blocking mode for this open operation and subsequent I/O operations
The following three logos are also Optional:
O_dsync waits for the physical I/O to complete each write operation. If the write operation does not affect reading the data just written, it does not wait for the attribute update of the file.
O_rsync is a read operation waiting for each file descriptor as a 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,
When o_dsync overwrites some existing content, the file time attribute will not be synchronously updated, and every write operation of o_sync will wait for the new file time before the return.
3.2 creat Function
# Include <fcntl. h> int creat (const char * pathname, mode_t mode) if a file descriptor opened in write-only mode is returned successfully,-1 is returned if a failure occurs.
Now you can use the following method to call open instead of Creat
Open (pathname, o_wronly | o_creat | o_trunc, mode );
3.3 close Function
# Include <fcntl. h> int close (INT filedes); if 0 is returned successfully,-1 is returned when an error occurs;
When a process is terminated, all opened file descriptors are automatically closed. Therefore, many programs use this function to disable the close function;
3.4 lseek Functions
# Include <unistd. h> off_t lseek (INT filedes, off_t offset, int where); a new file offset is returned successfully, and an error is returned-1;
The meaning of offset is related to the selection of where:
Seek_set sets the file offset to offset bytes from the start of the file;
Seek_cur sets the file offset to the current value plus offset (offset can be positive or negative );
Seek_end sets the file offset to the file length plus offset (offset can be positive or negative );
Call lseek (FD, 0, seek_cur) to determine the current offset of the opened file. You can also use this to test whether the file can be set as an offset. If FD is a pipe, FIFO, and network socket,-1 is returned, and errno is set to espipe;
#include <stdio.h>#include <unistd.h>int main(){ if(lseek(STDIN_FILENO,0,SEEK_CUR) == -1) printf("connot seek\n"); else printf("seek OK\n"); return 0;}
Compile and run the program.
[email protected]:/program# ./3-1 < /etc/motdseek OK[email protected]:/program# cat < /etc/motd | ./3-1connot seek
3.4.1 Empty files
When the file offset is greater than the length of the current file, an empty object is formed in the file. All the bytes in the file that have not been written are read as 0.
#include <stdio.h>#include <fcntl.h>#include <unistd.h>#define FILE_MODE S_IRUSR | S_IWUSR | S_IXUSRint main(){ char buf1[] = "abcde"; char buf2[] = "ABCDE"; int fd; if((fd = creat("foo",FILE_MODE)) < 0) { printf("creat file error\n"); return -1; } if(write(fd,buf1,5) != 5) { printf("write error\n"); return -1; } if(lseek(fd,1024,SEEK_SET) == -1) { printf("seek error\n"); return -1; } if(write(fd,buf2,5) != 5) { printf("write error\n"); return -1; } return 0;}
View File Size
[Email protected]:/Program # ls-l foo-rwx ------ 1 Root 1029 Nov 2 20:48 Foo [email protected]:/Program #
View the file content [email protected]: /Program # OD-C foo1_000 a B c d e \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 00000020 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0*0002000 a B c d e0002005 [email protected]: /Program #
We can see that all the unwritten bytes in the file are filled with 0.
3.5 read Function
# Include <unistd. h> ssize_t read (INT filedes, void * Buf, ssize_t nbytes); if the number of bytes read is returned successfully, if 0 is returned at the end of the file, an error is returned-1;
The read operation starts from the current file offset. Before the read operation returns, the file offset increases the number of bytes actually read. The actual number of bytes read may be smaller than that of nbytes.
3.6 write function
# Include <unistd. h> ssize_t write (INT filedes, const void * Buf, size_t nbytes); if the number of written bytes is returned successfully, the return value is generally nbytes, and-1 is returned if an error occurs;
For normal files, the write operation starts from the current offset of the file. If o_append is specified when the file is opened, the file offset is set to the end of the file, the file offset will increase the number of written bytes.
/* Copy the standard input to the standard output */
# Include <stdio. h> # include <unistd. h> # define buffsize 1024int main () {int N; char Buf [buffsize]; while (n = read (stdin_fileno, Buf, buffsize)> 0) if (write (stdout_fileno, Buf, n )! = N) {printf ("write error \ n"); Return-1;} If (n <0) printf ("read error \ n"); Return 0 ;}
[email protected]:/program# ./3-3hello world!hello world!
UNIX environment advanced programming notes (2) -- file I/O without buffering