Linux C file operation-System call (open (), read () ... ) and standard I/O library (fopen (), fread () ... )

Source: Internet
Author: User
Tags fread

I. What is a document

Before we tell the file operation, we need to know what the file is. You may feel ridiculous to see this, because a file is the simplest concept for a computer person, such as a text is a file, a work document is a file, and so on. But in Linux, the concept of files is far more than that, in Linux, everything (or almost everything) is a file. The file contains a lot of content, for example: You know the ordinary file is a file, directory is also a file, the device is a file, pipeline is a file and so on. For directories, devices, these operations can also be completely equivalent to the operation of plain text files, which is one of the most successful features of Linux.

second, the system calls

1. File descriptor

File descriptors are small numbers of open file devices that you can access through them, and how many file descriptors are available depends on the configuration of the system. But when a program starts running, it typically has 3 open file descriptors, which are

0: Standard input

1: Standard output

2: Standard error

Those math (i.e. 0, 1, 2) is a file descriptor because everything on Linux is a file, so standard input (stdin), standard output (stdout), and standard error (STDERR) can also be treated as files.

2, the system calls the common function

A, open system call

The prototype of the Open function is:

int Open(const char *path, int oflags);

int Open(const char *path, int oflags, mode_t mode);

Path, which is the full file name of the path, Oflags is the access mode (that is, how the file is opened, read-only, write-only, readable, writable, etc.), and mode is used to set the file's access rights. Specific optional parameters, you can view the manual page, not detailed here.

Open establishes a access path to a file or device, and if the call succeeds, returns a file descriptor that can be used by a function called by read, write, and other system calls, and the file description is unique, not shared with any other running process, and returns 1 on failure. and set the global variable errno to indicate the cause of blindness.

B. Write system call

The prototype of the Write function is:

size_t Write(int fildes, const void *buf, size_t nbytes);

Write writes the first nbytes bytes of a buffer buf to the file descriptor Fildes The associated file, returning the actual number of bytes written. A return of 0 means that no data is written, and 1 indicates an error occurred in the call, and the error code is saved in errno.

Note: Fildes must be a created file descriptor that is returned in an open call, or a standard input, output, or standard error such as 0, 1, 2.

C, read system call

The prototype of the Read function is:

size_t read(int fildes, void *buf, size_t nbytes);

The purpose of the read system call is to read the Nbytes bytes of data from the file associated with the file descriptor and place them in the data area buf, returning the number of bytes read, and returning-1 on failure.

D, close system call

The function prototypes for the close call are:

int close(int fildes);

The function of the close function is to finally file a descriptor Fildes the association between its corresponding file.

E, examples

With all that said, I'll give you a complete example of copying one file to another from a data file with 1M ' 0 ' characters. The file name is copy_system.cand the code is as follows:

#include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h>int main () { char c = ' n '; int in =-1, out = -1;//Opens the data file as read-only in = open ("Data.txt", o_rdonly);//Create a file in write-only mode, if the file does not exist create a new file//file owner has read and Write Permission out = open ("Copy_system.out.txt", O_wronly | O_creat, S_IRUSR | S_IWUSR);//Read a byte of data while (read (in, &c, 1) = = 1) {//write a byte of data write (out, &c, 1);} Close file descriptor Close (in), Close (out), return 0;}

Three, standard I/O Library

People with C programming experience will know Stdio header file, it is the standard IO Library of C language, in the standard IO library, and the underlying file description typeface corresponds to the stream, which is implemented as a pointer to the structure file. IO Library has a lot of functions, in order to correspond with the previous content, here is only the previous four functions corresponding to the function, the other functions, you can check the manual page.

A, fopen library functions

The prototype for the Fopen library function is:

file* fopen(const char *filename, const char *mode);

It is similar to the underlying system call open and returns a non-null pointer when successful. Null is returned on failure.

B, Fread library functions

The prototype for the Fread library function is:

size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);

It is similar to the underlying call to read, which reads Nitems data of size from stream to the buffer pointed to by PTR. The return value is the number of records successfully read into the buffer.

Note: Stream is a pointer to the file structure returned with the fopen function.

C, fwrite library functions

Prototype of the Fwrite library function:

size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);

It is similar to the underlying call to write, which reads the nitems length from the buffer pointed to by PTR to the data, and writes them to the file corresponding to the stream.

D, fclose library functions

The prototype for the Fclose library function is:

int fclose(FILE *stream);

It is similar to the system call close, which is to close the specified file stream stream.

Example

Similarly, the following is another implementation version of the previous example, which implements the same functionality as the previous example, but uses the standard I/O library instead of the system call, with the file name COPY_STDIO.C code as follows:

#include <stdio.h> #include <stdlib.h>int main () {int c = 0; FILE *pfin = NULL; File *pfout = null;//Open the data file as read-only pfin = fopen ("Data.txt", "R");//Open the copied new file in write-only mode pfout = fopen ("Copy_stdio.out.txt", "w"); /Read data while (Fread (&c, sizeof (char), 1, Pfin)) {//write Data fwrite (&c, sizeof (char), 1, pfout);} Close file stream fclose (Pfin); fclose (pfout); return 0;}

Of course, you can also use other library functions to complete the work, such as: with fgetc instead of fread, with FPUTC instead of fwrite.

iv. Relationship of file descriptors and file streams

Each file stream corresponds to an underlying file descriptor that you can use to mix the underlying input and output operations with the high-level file stream operation, but generally do not, because the consequences of data buffering are unpredictable. We can determine the underlying file descriptor used by the file stream by calling the Fileno function (the prototype is: int Fileno (file *stream)), which returns the file descriptor that points to the file stream. Instead, you can create a new file stream on an already opened file descriptor by calling the function Fdopen (the prototype is file* fdopen (int fildes, const char* mode), and the mode parameter is exactly the same as the fopen function, It must also conform to the access mode that was set when the file was initially opened.

However, under Linux programming, the system calls more, because many times the system call can provide more flexibility and more powerful functions, some operations are necessary to use system calls, for example, to create a file read and write locks must use system calls.

v. Performance comparisons between system calls and standard I/O

Take the code in this example to compare, two examples compiled after the file name of the executable is: Copy_system.exe and Copy_stdio.exe, under Linux with the time command to test its runtime as follows:

As can be seen from the test results, system calls are much less efficient than library functions. Why is it?

Because using system calls can affect the performance of the system. In contrast to a function call, when a system calls, Linux must switch from running user code to executing kernel code and then returning user code, so the overhead of system calls is larger than that of normal function calls. However, there are ways to reduce this overhead by minimizing the number of system calls in the program and making every system call complete as much work as possible.

And why does the library function do the same things so much more efficiently? This is because the library function arranges for the underlying system call only when the data satisfies the data block length (or buffer length), thus reducing the number of system calls and making every system call do as many things as possible, so the efficiency is relatively high.

Vi. Examples of simple methods to improve system invocation

Using the code back for each example (COY_SYSTEM.C), a slight modification would improve our efficiency, such as reading 1024 bytes at a time, and then saving the file named Copy_system2.c with the following code:

#include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h>int main () { Char Buff[1024];int in =-1, out = -1;int nread = 0;in = Open ("Data.txt", o_rdonly); out = open ("Copy_system2.out.txt", O_w ronly | O_creat, S_IRUSR | S_IWUSR);//Read and write 1024 bytes while ((Nread = read (in, buff, sizeof)) > 0) {write (out, buff, nread);} Close (in), Close (out), return 0;

The resulting executable file is Copy_system2.exe, and the time command is used to view its execution times as follows:

The comparison shows that its performance improves by an order of magnitude, and its efficiency is even more efficient than copying with a single character from a library function, at least on my machine.

Reference:

http://blog.csdn.net/ljianhui/article/details/10055665

Linux C file operation-System call (open (), read () ... ) and standard I/O library (fopen (), fread () ... )

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.