Unix system IO

This article is reproduced by the blogger
Original link: https://blog.csdn.net/u013075553/article/details/103395816

Unix system IO

file

In Linux, everything is a file. Every file has a type (type) to indicate its role in the system:

  • Normal files (regular file)contain arbitrary data
  • Index of (direction)相a group of files
  • The type of socket (socket)communication with a process on another machine

This blog mainly introduces ordinary files:

  • Text files:
    text file containing only ASCIIor Unicodegeneral character of the document, the text is a series of lines, each with a newline character \nat the end, which is a digital value 0xa, and the ASCIIcode of line feedthe characters (LF)the same. In Windowsand 网络协议among which are \r\n(0xd 0xa) to the end.
  • Binary files
    Binary files are ordinary files other than text files, such as our programs, pictures, videos, etc.

open a file

When we want to read or write a file, we first need to tell the system kernel that we want to access this file. The kernel ( open函数) will return a small non-negative integer ( 描述符), and we will use this descriptor in our subsequent operations.
At the beginning of the program, three files have been opened by default:

  • 0: standard input(stdin)
  • 1: standard output(stdout)
  • 2: standar error(stderr)
#include<sys/types.h>
#incldue<sys/stat.h>
#include<fcntl.h>

int open(char *filename,int flags,mode_t mode);

  • 1
  • 2
  • 3
  • 4
  • 5

Parameter introduction:

  • filename
    The name of the target file to be opened or created
  • When flags
    opens the file, you can pass in multiple parameter options, and use one or more of the following constants to perform operations to form falgs.
  • O_RDONLY: Read only open
  • O_WRONLY: Write only open
  • O_RDWR: The above three constants can be read and written
    , one must be specified and only one can be specified
  • O_CREAT: If the file does not exist, create it, you need to use the mode option. To specify the access rights of the new file
  • O_APPEND: Append write, if the file already has content, the data written when opening the file this time is appended to the end of the file without overwriting the original content
  • O_TRUNC: If the file exists, truncate it (delete the existing content and rewrite)
  • The mode
    mode parameter describes the access rights of the new file
  • S_IRUSR: The user (owner) can read this file
  • S_IWUSR: The user (owner) can write this file
  • S_IXUSR: The user (owner) can execute this file
  • S_IRGRP: Members of the owner's group can read this file
  • S_IWGRP: Members of the owner's group can write this file
  • S_IXGRP: Members of the owner's group can execute this file
  • S_IROTH: Other people (anyone) can read this file
  • S_IWOTH: Other people (anyone) can write this file
  • S_IXOTH: Other people (anyone) can execute this file

Close file

#include <unistd.h>

int close(int fd);

  • 1
  • 2
  • 3
  • fd: The descriptor of the file to be closed.
  • Return value: return 0 if successful
  • Return -1 on error

Note: When a process terminates, the kernel will automatically close all open files

Read file

#include <unistd.h>

ssize_t read (int fd, void *buf, size_t n);

  • 1
  • 2
  • 3

parameter:

  • fd : The descriptor of the file to be read.
  • buf : the buffer into which the read data should be put.
  • count : The number of bytes to be read.

return value:

  • Return the number of bytes read if successful, or 0 if the end of the file has been reached
  • If an error occurs, it returns -1 and sets the value of the variable errno.

Note: size_t here is an unsigned integer, and ssize_t is a signed integer.

Write file

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t n);

  • 1
  • 2
  • 3

parameter:

  • fd : file descriptor;
  • buf : The designated buffer, that is, a pointer, points to a memory unit;
  • n : the number of bytes specified in the file to be written;

return value:

  • The number of bytes written to the document (success); -1 (error)

writeThe function writes bufthe nnumber of bytes 描述符in the file pointed to by fd, returns the number of bytes written when it succeeds, and returns -1 when it fails.

example

#include "csapp.h"

int main(void)
{
char c;
int fd = open(“abc.txt”,O_WRONLY|O_CREAT|O_TRUNC);
while(read(STDIN_FILENO, &c, 1) != 0)
write(fd, &c, 1);
close(fd);
exit(0);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

This is a relatively simple example of storing the content entered into the terminal in a file abc.txt.
The following is the result of the operation:

hpj@黄培纪:/mnt/d/code/C/Computer Systems/chap10_code$ ./test
test text
^C

 
  
  
  • 1
  • 2
  • 3

abc.txtThe contents are:

test text

Note: There is also a newline character (\n) above which is not displayed

  • 1
  • 2
  • 3

Redirect

In the kernel, there are three related data structures used to represent the opened file:

  • Descriptor table
    Each process has its own descriptor table (Descriptor table), the table items are indexed by the file descriptor
  • File table is
    a collection of opened files. All processes share this table. The entry includes the location of the file and the reference count (the number of descriptors currently pointing to the entry). Until this number becomes 0, the system kernel will delete it, otherwise it will not.
  • v-nodeTable
    All processes share this table, and each table entry contains most of the information of the stat structure.


Let's look at a code:

#include "csapp.h"

int main(int argc, char argv[])
{
int fd1, fd2, fd3;
char c1, c2, c3;
char fname = argv[1];
fd1 = Open(fname, O_RDONLY, 0);
fd2 = Open(fname, O_RDONLY, 0);
fd3 = Open(fname, O_RDONLY, 0);
dup2(fd2, fd3);

<span class="token function">Read</span><span class="token punctuation">(</span>fd1<span class="token punctuation">,</span> <span class="token operator">&amp;</span>c1<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Read</span><span class="token punctuation">(</span>fd2<span class="token punctuation">,</span> <span class="token operator">&amp;</span>c2<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Read</span><span class="token punctuation">(</span>fd3<span class="token punctuation">,</span> <span class="token operator">&amp;</span>c3<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"c1 = %c, c2 = %c, c3 = %c\n"</span><span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c2<span class="token punctuation">,</span> c3<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">Close</span><span class="token punctuation">(</span>fd1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Close</span><span class="token punctuation">(</span>fd2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Close</span><span class="token punctuation">(</span>fd3<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Read the following file abcde.txt:

abcde

 
  
  
  • 1

The running results are as follows:

hpj@黄培纪:/mnt/d/code/C/Computer Systems/chap10_code$ ./ffiles1 abcde.txt
c1 = a, c2 = a, c3 = b

 
  
  
  • 1
  • 2

This is because a dup2function is used here to change the fd3file pointed to by the descriptor. This is the redirection process, as shown in the following figure:

Let's look at another example:

#include "csapp.h"

int main(int argc, char argv[])
{
int fd1, fd2, fd3;
char fname = argv[1];
fd1 = Open(fname, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR);
Write(fd1, “pqrs”, 4);

fd3 <span class="token operator">=</span> <span class="token function">Open</span><span class="token punctuation">(</span>fname<span class="token punctuation">,</span> O_APPEND<span class="token operator">|</span>O_WRONLY<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Write</span><span class="token punctuation">(</span>fd3<span class="token punctuation">,</span> <span class="token string">"jklmn"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fd2 <span class="token operator">=</span> <span class="token function">dup</span><span class="token punctuation">(</span>fd1<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">/* Allocates new descriptor */</span>
<span class="token function">Write</span><span class="token punctuation">(</span>fd2<span class="token punctuation">,</span> <span class="token string">"wxyz"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Write</span><span class="token punctuation">(</span>fd3<span class="token punctuation">,</span> <span class="token string">"ef"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">Close</span><span class="token punctuation">(</span>fd1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Close</span><span class="token punctuation">(</span>fd2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Close</span><span class="token punctuation">(</span>fd3<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

The running results are as follows:

hpj@黄培纪:/mnt/d/code/C/Computer Systems/chap10_code$ ./ffiles3 abc.txt

 
  
  
  • 1

abc.txtThe content of the file is entered as follows:

pqrswxyznef

 
  
  
  • 1

Into the general process:
First, Write(fd1, "pqrs", 4);to pqrswrite to abc.txtin;
then Write(fd3, "jklmn", 5);the jklmnwrite to abc.txtin;
then under fd1 original point, and Write(fd2, "wxyz", 4);the wxyzwriting to pqrsthe back, to jklmnthe jklmcover, into wxyzn;
and finally Write(fd3, "ef", 2);in wxyznthe continued Write ef.
So abc.txtthe content is pqrswxyznef.

Finally, let's look at an example:

#include "csapp.h"

int main(int argc, char argv[])
{
int fd1;
int s = getpid() & 0x1;
char c1, c2;
char fname = argv[1];
fd1 = Open(fname, O_RDONLY, 0);
Read(fd1, &c1, 1);
if (fork()) {
int status;
wait(&status);
Read(fd1, &c2, 1);
printf(“Parent: c1 = %c, c2 = %c\n”, c1, c2);
} else {
/* Child */
Read(fd1, &c2, 1);
printf(“Child: c1 = %c, c2 = %c\n”, c1, c2);
}
return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

The read abcde.txtresults are as follows:

hpj@黄培纪:/mnt/d/code/C/Computer Systems/chap10_code$ ./ffiles2 abcde.txt
Child: c1 = a, c2 = b
Parent: c1 = a, c2 = c

 
  
  
  • 1
  • 2
  • 3


The child process also copies the descriptor table of the parent process, but still points to the same file table entry, so the execution Read(fd1, &c2, 1);result is different.


Reference

                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-b6c3c6d139.css" rel="stylesheet">
                </div>
This article is reproduced by the blogger
Original link: https://blog.csdn.net/u013075553/article/details/103395816

Unix system IO

file

In Linux, everything is a file. Every file has a type (type) to indicate its role in the system:

  • Normal files (regular file)contain arbitrary data
  • Index of (direction)相a group of files
  • The type of socket (socket)communication with a process on another machine

This blog mainly introduces ordinary files:

  • Text files:
    text file containing only ASCIIor Unicodegeneral character of the document, the text is a series of lines, each with a newline character \nat the end, which is a digital value 0xa, and the ASCIIcode of line feedthe characters (LF)the same. In Windowsand 网络协议among which are \r\n(0xd 0xa) to the end.
  • Binary files
    Binary files are ordinary files other than text files, such as our programs, pictures, videos, etc.

open a file

When we want to read or write a file, we first need to tell the system kernel that we want to access this file. The kernel ( open函数) will return a small non-negative integer ( 描述符), and we will use this descriptor in our subsequent operations.
At the beginning of the program, three files have been opened by default:

  • 0: standard input(stdin)
  • 1: standard output(stdout)
  • 2: standar error(stderr)
#include<sys/types.h>
#incldue<sys/stat.h>
#include<fcntl.h>

Guess you like

Origin blog.csdn.net/xiongdan626/article/details/103426127