Recently in the study of Apue, so by the way the Daily Record, on the one hand to consolidate the knowledge of learning, on the other hand also for the same learning Apue children's shoes to provide a reference.
This series is based on learning "UNIX Environment Advanced Programming" a book summed up, if there are errors please advise.
Apue mainly discusses three parts: File io, concurrency, interprocess communication.
Standard IO: The advantage is high portability, the disadvantage is that performance is worse than system IO, and the function is not rich in system IO.
System IO: Because it is a system call function directly provided by the kernel, performance is higher than standard IO, but portability is worse than standard IO.
Signal + multi-process;
System V: Also known as XSI, supports the following three ways:
MSG: Message queue;
SEM: signal volume;
SHM: Shared storage;
Socket: socket (network communication);
This series of blog is around these content to learn and summed up, but apue a book is mainly about the Unix environment, and LZ with the Linux environment, so this series of all the content is based on the Linux environment, only for the children's shoes reference. LZ as much as possible to talk about the principle, less about the specific use of functions, when using the LZ mentioned functions, such as the development environment of the Man manual conflict, the man manual shall prevail.
============================== Gorgeous split-line ==============================
Well, through a simple introduction to believe that you have a general understanding of the structure of Apue, and then start today's topic: File IO.
All of the IO operations today are standard IO, which I'll identify separately if it's a dialect.
One of the first concepts to understand is the file location pointer.
When we open a file to read and write to it, how can we know where to begin to read (write) the file? In fact, the standard library prepared a tool to assist us read and write files, it is the file location pointer . When we use the standard library function to manipulate the file, it will automatically find the location of our operation according to the file location pointer, and it will automatically modify the point as we read and write, instead of manually recording and modifying the file's operation location ourselves. It's so convenient to use that you don't feel it at all, but you have to know what it does to get a better understanding of file IO.
1 fopen- stream open functions23 #include <stdio.h>45 FILE *fopen (constcharconstchar *mode);
This is the first function to learn today, before manipulating the file, we need to open the file through the fopen () function, which we can tell the operating system which file we want to manipulate, and in what way we manipulate the file.
Path: The file path to manipulate.
Mode: The way the file is opened, this open method is divided into 6 kinds.
R: Opens the file in a read-only manner, and the file location pointer is positioned to the top of the file. If the file you want to open does not exist, an error occurs.
r+: Opens the file in read-write mode, and the file location pointer is positioned to the top of the file. If the file you want to open does not exist, an error occurs.
W: Opens the file in a write-only manner if the file does not exist and is truncated to 0 bytes if the file already exists, and the file location pointer is positioned to the top of the file.
w+: Opens the file as read-write , creates if the file does not exist, is truncated to 0 bytes if the file already exists, and the file location pointer is positioned to the top of the file.
A: Open the file as an append , if the file does not exist, and the file location pointer is positioned after the last valid character of the file (Eof,end of the files).
A +: Opens the file as read and append , if the file does not exist, and the read file location pointer is initialized to the top of the file, but is always written after the last valid character (Eof,end of the The file).
File is a structure defined by the standard library, children's shoes do not attempt to manually modify the contents of the structure to achieve the operation of the file, be sure to use the standard library functions to manipulate the file.
This function returns a pointer to the file type, which is used as the credential for our open files, and all subsequent operations on the file need to use this pointer, and you must not forget to call the fclose (3) function to release the resource after use.
If the function returns a pointer to NULL, the file open fails, and the reason for the specific failure can be obtained through errno.
1 fclose- close a stream23 #include <stdio.h>45int fclose (FILE *FP);
This function corresponds to the fopen (3) function, and when we have finished using a file, we need to call the fclose (3) function to release the associated resource, otherwise it will cause a memory leak. When a file pointer is successfully released by the fclose (3) function, the pointer will not be used again, and the fopen (3) function needs to be called if it needs to be opened again.
The return value of the Fp:fopen (3) function is passed in as a parameter.
1 fgets- input of strings23 #include <stdio.h>45int fgetc (FILE *stream); 6 7 Char *fgets (charint size, FILE *stream);
Reads a string from the input stream stream to backfill to the space pointed to by S.
Here comes the concept of a stream, what is this stream, which is a "stream", which is actually an abstraction of the operating system for something that can be manipulated like a file. It does not flow like a stream of natural streams, but it is usually either without data or a lump of data at a sudden. Of course, the stream may not necessarily be a file, such as the system for each process by default open three Stream:stdin, stdout, stderr, they are not files, that is, and the file has the same way of operation, so the same is abstracted as "flow."
This function does not solve the problem that the Get (3) function can cause an array out of bounds, but by sacrificing the correctness of the data to ensure that the program does not have an array out of bounds error, in fact, masked the problem of gets (3).
The function will return if it encounters the following four scenarios:
1. When the amount of data read reaches size-1;
2. When the read character encounters \ n;
3. When the read character encounters EOF;
4. When the read encounters an error;
And it adds a \ s to the last face of the data being read.
Returns s when successful.
Returning NULL indicates an error occurred or the end of the Strem (EOF) was read.
4.fread (3), fwrite (3)
1 fread, fwrite-binary stream input/output23 #include <stdio.h>4 5 size_t fread (void *ptr, size_t size, size_t nmemb, FILE *stream); 6 7 size_t fwrite (constvoid *ptr, size_t size, size_t nmemb, FILE *stream);
The two functions are most frequently used to read and write the stream, usually to read and write files.
Ptr:fread (3) Backfill the data read from the stream to the location pointed to by PTR, and fwrite (3) writes the data read from the location where PTR is only going to write to the stream;
Size: The number of bytes occupied by each object to be read;
NMEMB: How many objects to read;
Stream: The source or whereabouts of the data;
Note that the return value of these two functions represents the number of successful read (write) objects, not the number of bytes!
Read (buf, 1, FP); Read 10 objects, 1 bytes per object
Read (buf, 1, FP); Read 1 objects, 10 bytes per object
There is no difference between the two ways when the amount of data is plentiful.
but!! when the amount of data is less than the integer multiple of a size byte, the last object of the second method fails to read. For example, if the data is only 45 bytes, the return value of the second method is 4 because it can only read 4 objects successfully.
So usually the first way to read and write data is used more commonly.
1Atoi, Atol, Atoll, Atoq-convert astringTo an integer2 3#include <stdlib.h>4 5 intAtoiConst Char*nptr);6 LongAtolConst Char*nptr);7 Long LongAtoll (Const Char*nptr);8 Long LongAtoq (Const Char*NPTR);
Atoi (3) function family here to mention, mainly for the following printf (3) function family to do a cushion.
The function of these functions is to conveniently convert a number in a string form to a number of the corresponding numeric type.
The above sentence may have a bit of au kou, to show you an example to understand, the following is pseudo-code.
1 Char " 123abc456 " ; 2 int 0 ; 3 i = atoi (str);
The result of I will become 123. These functions convert a number in front of a non-valid number in a string. If it is unfortunate that the first character in the string is not a valid number, then they will return 0.
1printf, fprintf, sprintf, snprintf-formatted output conversion2 3#include <stdio.h>4 5 intprintfConst Char*format, ...);6 intfprintf (FILE *stream,Const Char*format, ...);7 intsprintfChar*STR,Const Char*format, ...);8 intsnprintfChar*STR, size_t size,Const Char*format, ...);
printf (3) function Everyone must not be unfamiliar, should write Hello world! from When it came into contact with the bar, so I do not introduce more, the main introduction of two of content.
One is the interview often test a problem, with so long printf (3) function, have you noticed that its return value represents what?
The return value of printf (3) indicates the number of valid characters that were successfully printed, not including.
Another thing to say is that just now we mentioned the Atoi (3) function family, which is responsible for converting the string to a number, then there is no function can convert the number to a string, in fact, through sprintf (3) or snprintf (3) can be.
With these two functions, you can not only easily convert numbers to strings, but you can also arbitrarily stitch multiple strings into a complete string.
Here is a direct explanation of the snprintf (3) function.
STR: After stitching, the result is backfill to the point where the pointer is pointing;
Size:size-1 is the maximum length to backfill into STR, the portion of the data beyond that length is discarded, and then added to the tail of the stitched string;
Format: formatted string, used in the same way as printf (3), no longer repeat;
... : Formatting the parameters of the string, using the same as printf (3);
This function, like fputs (3), only obscures the problem that sprintf (3) can cause an array to cross the boundary, by sacrificing the correctness of the data to ensure that the program does not cross the array of errors.
1scanf, fscanf, sscanf-Input Format Conversion2 3#include <stdio.h>4 5 intscanfConst Char*format, ...);6 intFSCANF (FILE *stream,Const Char*format, ...);7 intsscanfConst Char*STR,Const Char*format, ...);
scanf (3) function family believe also not too much introduction, the only thing to emphasize is:scanf (3) function supports a variety of format parameters, except that%s is not safe to use, may cause the array out of bounds, so when the need to receive user input can be used when the fgets ( 3) and other functions to replace.
1 fgetpos, fseek, Fsetpos, Ftell, rewind- reposition a stream23 #include <stdio.h >45intlongint whence); 6 7 long ftell (FILE *stream); 8 9 void Rewind (FILE *stream);
The functions of the fseek (3) function family are used to control and obtain the position of the file position pointer, which allows us to read and write files flexibly.
Introduce the parameter list of the fseek (3) function:
Stream: This does not need to introduce more, is to prepare to modify the file location pointer file stream;
Offset: Offsets based on the whence parameter;
Whence: Where relative to the file, there are three macro definitions that can be used as its parameters: Seek_set (top of file), Seek_cur (current position), or seek_end (end of file);
Successful return 0, Failure returns-1, and errno is set.
See the parameter list alone maybe you have some doubts, so I'll write some simple pseudo-code as an example:
1 fseek (FP,-/// 10 bytes forward from the current position. 2// can manufacture an empty file, such as the one that was generated when the Thunderbolt was first downloaded.
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 byte size.
There is another issue that deserves your attention:
The parameters and return values of Fseek (3) and Ftell (3) Use a long, so the value range is -2GB ~ (2gb-1), and Ftell (3) can only represent the file size within 2g-1, so use the Fseeko (3) and Ftello (3) functions to replace it But they are only dialects (SUSv2, posix.1-2001.).
Because these two functions are old, so the design of the time to think that the range of +-2GB is enough to use, but not aware of the rapid development of science and technology today, 2GB size of the file has been completely unable to meet the actual needs.
The Rewind (3) function moves the file position pointer to the starting position of the file, equivalent to:
1 (void0L, Seek_set)
1getline-delimitedstringinput2 3#include <stdio.h>4 5ssize_t Getline (Char**lineptr, size_t *n, FILE *stream);6 7Feature Test Macro Requirements forGLIBC (See Feature_test_macros (7)):8 9 getline ():TenSince glibc2.10: One_posix_c_source >=200809L|| _xopen_source >= the ABefore glibc2.10: -_gnu_source
This function is a very useful function, it can help us to get a row of data at a time, regardless of how long this data.
LINEPTR: The address of a first-level pointer, which fills in the data that is read to the position pointed to by a first-level pointer and backfill > that position into the parameter. The pointer must initially be set to NULL, which determines whether a new memory needs to be allocated based on whether the pointer is null.
N: Is the total size of the requested memory buffer that is backfill by the function, and the length must initially be set to 0.
Although it is very useful, but children's shoes do not be happy too early, the function only support the GNU standard, so is the dialect, we still encapsulate a spare bar.
Also, to use this function, you must specify the-d_gnu_source parameter at compile time:
1 gcc -d_gnu_source
Of course, if you do not want to add parameters at compile time, you can also #define _gnu_source before referencing the header file, just ugly.
Another way is to configure CFLAGS + =-d_gnu_source in makefile, which eliminates the hassle of manually writing parameters at compile time, and avoids the ugliness in the code.
Well, it's not too early, let's write it here today.
(i) Learn apue together file IO