(1) Learning APUE file IO and apue file io together

Source: Internet
Author: User
Tags rewind

(1) Learning APUE file IO and apue file io together

.

.

.

.

.

I have been learning APUE recently. By the way, I have recorded what I learned every day. On the one hand, I want to consolidate my learning knowledge and on the other hand, I want to provide a reference for the kids who are also learning APUE.

This series of blog posts are summarized in the book "Advanced Programming for UNIX environments". If you have any errors, please advise me.

APUE mainly discusses three parts: file IO, concurrency, and inter-process communication.

File IO:

Standard I/O: the advantage is high portability, and the disadvantage is that the performance is worse than the system I/O, and the function is not rich in system I/O.

System IO: because it is a system call function directly provided by the kernel, the performance is higher than the standard IO, but the portability is worse than the standard IO.

Concurrency:

Signal + multi-process;

Multithreading;

Inter-process communication:

FIFO: MPS queue;

System V: XSI. It supports the following three methods:

Msg: Message queue;

Sem: semaphore;

Shm: shared storage;

Socket: Socket (network communication );

This series of blog posts are learned and summarized based on these content,However, the book APUE mainly talks about the Unix environment, while LZ uses the Linux environment. Therefore, all the content in this series of blog posts is based on the Linux environment and is only for your reference. LZ should talk about the principle as much as possible, and less about the specific use of functions. If the man manual mentioned by LZ conflicts with the man manual of the development environment, the man manual shall prevail.

 

= ======================================

 

Well, I believe you have a general understanding of the structure of APUE through a simple introduction. Next we will start with today's topic: file IO.

All I/O operations mentioned today are standard I/O operations. I will identify them separately if they are dialects.

One of the first concepts to understand is the file location pointer.

When we open a file to read and write it, how can we know where to start reading (writing) the file? In fact, a tool is provided in the standard library to help us read and write files.File Location pointer. When we use a standard library function to operate a file, it will automatically locate the position we want to operate based on the file location pointer, And will automatically modify the direction with our read/write operations, instead of manually recording and modifying the file operation location. It is very convenient to use, so that you do not feel it, but to better understand the file IO, you must know its role.

1. fopen (3)

1 fopen - stream open functions2 3 #include <stdio.h>4 5 FILE *fopen(const char *path, const char *mode);

This is the first function to be learned today. Before operating a file, we need to open the file through the fopen () function. Through this function, we can tell the operating system which file we want to operate on, and how to operate the file.

Parameter List:

Path: path of the file to be operated.

Mode: file opening method. There are 6 open methods.

R:Read-OnlyOpen the file, and the file location pointer will be located at the beginning of the file. If the file to be opened does not exist, an error is returned.

R +: UseRead/writeOpen the file, and the file location pointer will be located at the beginning of the file. If the file to be opened does not exist, an error is returned.

W:Write onlyTo open the file. If the file does not exist, it is created. If the file already exists, it isTruncationIt is 0 bytes and the file position pointer is located at the beginning of the file.

W +:Read/writeTo open the file. If the file does not exist, it is created. If the file already exists, it isTruncationIt is 0 bytes and the file position pointer is located at the beginning of the file.

A: UseAppendOpen the file. If the file does not exist, the file is created and the file location pointer is located after the last valid character (EOF, end of the file ).

A +: UseRead and appendOpen the file. If the file does not exist, the file is created and the pointer to the Read File Location is initialized to the beginning of the file, but it is always written to the end of the last valid character (EOF, end of the file ).

Return Value:

FILE is a structure defined by the standard library. Do not manually modify the content in the structure to perform FILE operations. You must use the standard library function to operate files.

This function returns a FILE pointer, which serves as the credential for opening the FILE. This pointer is required for all subsequent operations on this FILE, do not forget to call the fclose (3) function to release resources after use.

If the function returns a pointer to NULL, it indicates that the file fails to be opened. You can use errno to obtain the cause of the failure.

 

2. fclose (3)

1 fclose - close a stream2 3 #include <stdio.h>4 5 int fclose(FILE *fp);

This function corresponds to the fopen (3) function. After we use a file, we need to call the fclose (3) function to release related resources. Otherwise, memory leakage will occur. After a FILE pointer is successfully released by the fclose (3) function, the content pointed to by this pointer cannot be used again. To open the FILE again, you must call the fopen (3) function.

Parameter List:

The Return Value of the fp: fopen (3) function is passed in as a parameter.

 

3. fgets (3)

1 fgets - input of strings2 3 #include <stdio.h>4 5 int fgetc(FILE *stream);6 7 char *fgets(char *s, int size, FILE *stream);

Reads a string from the input stream and refills it into the space pointed to by s.

Here we see a concept of stream. What is this stream? It is actually an abstraction of the operating system for something that can be operated like a file. It is not like a natural stream of small streams, but it is usually either no data or a glimpse of data. Of course, stream is not necessarily a file. For example, the system opens three streams for each process by default: stdin, stdout, and stderr. They are not files, it is the same operation method as the file, so it is also abstracted as a "stream ".

This function does not solve the array out-of-bounds problem that may be caused by the gets (3) function. Instead, it sacrifices the correctness of the obtained data to ensure that the program will not encounter array out-of-bounds errors, it actually masks the problem of gets (3.

This function returns the following four conditions:

1. When the read data volume reaches size-1;

2. When \ n is read;

3. When the read character encounters EOF;

4. When reading an error;

In addition, it adds \ 0 to s to the end of the read data.

Return Value:

Returns s if the call is successful.

If the return value is NULL, an error is returned or an error is returned to the end of the strem (EOF ).

 

4. fread (3), fwrite (3)

1 fread, fwrite - binary stream input/output2 3 #include <stdio.h>4 5 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);6 7 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

 

These two functions are most frequently used to read and write streams, which are usually used to read and write files.

Parameter List:

Ptr: fread (3) backfill the data read from stream to the position pointed to by ptr; fwrite (3) write the data read from only the position specified by the ptr to the stream;

Size: the number of bytes occupied by each object to be read;

Nmemb: the number of objects to read;

Stream: data source or destination;

Return Value:

  Note that the return values of these two functions indicate the number of successfully read (written) objects, rather than the number of bytes!

For example:

Read (buf, 1, 10, fp); // read 10 objects, one byte for each object

Read (buf, 10, 1, fp); // read 1 object, each with 10 bytes

When the data volume is sufficient, there is no difference between the two methods.

But !!When the data volume is less than an integer multiple of the size bytes, the last object of the second method fails to be read. For example, if the data contains only 45 bytes, the returned value of the second method is 4 because it can only successfully read four objects.

Therefore, the first method is generally used to read and write data.

 

5. atoi (3)

1 atoi, atol, atoll, atoq - convert a string to an integer2 3 #include <stdlib.h>4 5 int atoi(const char *nptr);6 long atol(const char *nptr);7 long long atoll(const char *nptr);8 long long atoq(const char *nptr);

 

The atoi (3) function family is mentioned here to pave the way for the printf (3) function family below.

These functions are used to easily convert a number in the string form into a number of the corresponding numeric type.

The above sentence may be a bit confusing. You can understand it by looking at an example. below is the pseudocode.

1 char *str = "123abc456";2 int i = 0;3 i = atoi(str);

 

The result of I will be 123. These functions convert numbers before an invalid number in a string. If the first character in the string is unfortunately not a valid number, they return 0.

 

6. printf (3)

1 printf,   fprintf,  sprintf,  snprintf - formatted output conversion2 3 #include <stdio.h>4 5 int printf(const char *format, ...);6 int fprintf(FILE *stream, const char *format, ...);7 int sprintf(char *str, const char *format, ...);8 int snprintf(char *str, size_t size, const char *format, ...);

 

The printf (3) function is no stranger to everyone. You should write Hello World! So I will not introduce it much. I will mainly introduce two things.

One is an interview question. After using the printf (3) function for so long, have you noticed what the return value represents?

The return value of printf (3) indicates the number of valid characters successfully printed, excluding \ 0.

Another point is that we mentioned the atoi (3) Function Family, which is responsible for converting strings into numbers. Is there any function that can convert numbers into strings, in fact, you can use sprintf (3) or snprintf (3.

With these two functions, you can not only easily convert numbers into strings, but also splice multiple strings into a complete string.

The snprintf (3) function is described here.

Parameter List:

Str: the result after splicing will be refilled to the position pointed to by this pointer;

Size: size-1 is the maximum length refilled to str. If the data exceeds this length, it is discarded and \ 0 is appended to the end of the concatenated string;

Format: format the string. Its usage is the same as that of printf (3;

...: Format the string parameter. Its usage is the same as that of printf (3;

Like fputs (3), this function only masks the array out-of-bounds problem that sprintf (3) may cause. It ensures that the program will not encounter array out-of-bounds errors by sacrificing data correctness.

 

7. scanf (3)

1 scanf,  fscanf, sscanf - input format conversion2 3 #include <stdio.h>4 5 int scanf(const char *format, ...);6 int fscanf(FILE *stream, const char *format, ...);7 int sscanf(const char *str, const char *format, ...);

 

Scanf (3) function families do not need to be described too much. The only thing to emphasize here is:The scanf (3) function supports multiple formatting parameters, but % s is not safe to use, and may cause array overflow.Therefore, you can use functions such as fgets (3) to receive user input.

 

8. fseek (3)

1 fgetpos, fseek, fsetpos, ftell, rewind - reposition a stream2 3 #include <stdio.h>4 5 int fseek(FILE *stream, long offset, int whence);6 7 long ftell(FILE *stream);8 9 void rewind(FILE *stream);

 

Fseek (3) Functions of the function family are used to control and obtain the position of the file location pointer, so that we can flexibly read and write files.

This section describes the parameter list of the fseek (3) function:

Stream: this does not need to be introduced anymore. It is the file stream for modifying the file location pointer;

Offset: the offset based on the whence parameter;

Whence: relative to the file; three macro definitions can be used as its parameters: SEEK_SET (first of the file), SEEK_CUR (current location), or SEEK_END (end of the file );

Return Value:

0 is returned for success,-1 is returned for failure, and errno is set.

You may still be confused when you look at the parameter list separately, so I will write some simple pseudo code as an example:

1 fseek (fp,-10, SEEK_CUR); // offset 10 bytes from the current position. 2 fseek (fp, 2 GB, SEEK_SET); // you can create an empty file, such as the file produced by thunder at the beginning of download.

The ftell (3) function obtains the position of the file pointer in bytes.

Fseek (fp, 0, SEEK_END) + ftell (3) can calculate the total file size in bytes.

There is another issue worth your attention:

The fseek (3) and ftell (3) parameters and return values use long, so the value range is-2 GB ~ (2GB-1), while ftell (3) can only represent the file size within 2G-1, so you can use the fseeko (3) and ftello (3) functions to replace them, but they are just dialects (SUSv2, POSIX.1-2001 .).

Because these two functions are relatively old, we thought that the value range of +-2 GB was enough at the design time, and did not realize that technology is developing so rapidly today, 2 GB files cannot meet the actual needs.

The rewind (3) function moves the file position pointer to the start position of the file, which is equivalent:

1 (void) fseek(stream, 0L, SEEK_SET)

 

 

9. getline (3)

 1 getline - delimited string input 2  3 #include <stdio.h> 4  5 ssize_t getline(char **lineptr, size_t *n, FILE *stream); 6  7 Feature Test Macro Requirements for glibc (see feature_test_macros(7)): 8  9 getline():10     Since glibc 2.10:11         _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 70012     Before glibc 2.10:13         _GNU_SOURCE

 

This function is a very useful function that can help us get a row of data at a time, regardless of how long the data is.

Parameter List:
Lineptr: the address of a level-1 pointer. It fills in the read data to the position pointed to by the level-1 pointer, and fills the> position in the parameter. The pointer must be set to NULL at first. This function determines whether to allocate new memory based on whether the pointer is NULL.
N: The total size of the memory buffer applied for by this function. The length must be set to 0 at the beginning.
Although it is very easy to use, it is too early for you to be happy. This function only supports the GNU standard, so it is a dialect. You should encapsulate it as a backup.

In addition, to use this function, you must specify the-D_GNU_SOURCE parameter during compilation:

1 $> gcc -D_GNU_SOURCE

 

Of course, if you do not want to add parameters during compilation, you can also # define _ GNU_SOURCE before referencing the header file, which is ugly.

Another way is to configure CFLAGS + =-D_GNU_SOURCE in makefile, which saves the trouble of manually writing parameters during compilation and avoids the ugliness in the code.

 

Well, it's not too early. I will write it here today.

 

Related Article

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.