linux c programming: standard IO library

The open, read, and write functions are used when operating on files as described above. This chapter will introduce stream-based file manipulation methods: fopen, fread, and fwrite. What is the difference between these two methods. 1 is a buffered file system and the other is a non-buffered file system

The buffered file system uses fopen, fread, fwrite, fgetc, fputc, fputs and other functions to operate. The characteristics of the buffered file system are: open up a "buffer" in the memory for use by each file in the program; when performing the operation of reading a file, read the data from the disk file into the memory "buffer" first, and then fill it up. Then read the required data from the memory "buffer" accordingly. When performing the operation of writing a file, the data is first written into the memory "buffer", and then the file is written after the memory "buffer" is full. It can be seen from this that the size of the memory "buffer" affects the number of actual external memory operations. The larger the memory "buffer" is, the fewer times the external memory is operated, and the execution speed and efficiency are high. In general, the size of the file "buffer" depends on the machine. fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind, etc.

 

Unbuffered system:

The buffer file system manages files with the help of file structure pointers, and accesses files through file pointers. It can read and write characters, strings, formatted data, and read and write binary data. The non-buffered file system depends on the operating system. Reading and writing files through the functions of the operating system is a system-level input and output. It does not set a file structure pointer and can only read and write binary files, but it has high efficiency and high speed.

 

As can be seen from the above description differences, fopen is a c standard function with good portability; while open is a linux system call with limited portability. From the perspective of file IO, the non-buffered system belongs to the low-level IO function, and the buffered system belongs to the high-level IO function. A simple distinction between low-level and high-level is: who is closer to the system kernel. Low-level file IO runs in kernel mode, and high-level file IO runs in user mode.

Look at the code below

#include <stdio.h>

const char *pathname="/home/zhf/test1.txt

void read_file_by_stream(){

FILE *fp;

const char * type="r";

char *string;

int c;

fp=fopen(pathname,type);

c=fgetc(fp);

printf("%c",c);

}

The fopen and fgetc functions are used here to read file open and read.

Prototype of fopen:

FILE *fopen(const char *restrict pathname, const char *restrict type);

The opening method is as follows:

Prototype of fgetc function:

int fgetc(FILE *fp);  returns a character read. returns an integer

The previous code can only read one character at a time, so to read the content of the entire file, it is necessary to collect the loop. The code is modified as follows

void read_file_by_stream(){

FILE *fp;

const char * type="r";

char *string;

int c;

fp=fopen(pathname,type);

if (ferror(fp)){

printf("open file error");

}

while((c=fgetc(fp)) != EOF){

printf("%c",c);

}

fclose(fp);

}

 

ferror is to judge whether there is an error when the file is opened, and if so, it will prompt

c=fgetc(fp)) != EOF: To judge whether the end of the file is read, use the method of comparing with  EOF . EOF is a negative value, usually -1, because the return value of fgetc is to convert unsigned char to int . If the most significant bit is 1 , it will not make the return value negative. So as long as the return value of fgetc is not EOF , it means that you can continue to read characters.

 

fgetc can only read one character at a time, which is too inefficient. Is it possible to read one row of data at a time? The method is to use the fgets function

char *fgets(char *buf,int n,FILE *fp)

 

#include <stdio.h>

const char *pathname="/home/zhf/test1.txt";

void read_file_by_stream(){

FILE *fp;

const char * type="r";

char buf[100];

char *string;

int c;

fp=fopen(pathname,type);

if (ferror(fp)){

printf("open file error");

}

while(fgets(buf,10,fp) != NULL){

printf("The content is %s",buf);

}

 

fclose(fp);

}

When the returned pointer will not be empty, read the data of each row

The content is abcde

The content is kjkl

Of course, the gets function can also be used , the difference is that the length of the buffer cannot be specified, and fgets must specify the length of the buffer. fgets reads until the next newline, but no more than n-1 characters. The corresponding input functions are fputc and fputs, which will not be introduced here.

 

The fgetc and fgets described above can only read one or a line of characters. And it will stop if there are null characters in the file. Especially during network operations, various symbols are written. In this case, you need to use binary I/O , that is, the fread and fwrite functions

fwrite:

  1. size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);  
  2. -- buffer: pointer to the data block  
  3. -- size: The size of each data, the unit is Byte ( for example: sizeof(int) is 4)  
  4. -- count: the number of data  
  5. -- stream: file pointer  

Call format: fwrite(buf, sizeof(buf), 1, fp); the return value of successful writing is 1 ( ie count)

Calling format: fwrite(buf,1,sizeof(buf),fp); if the write is successful, it will return the number of data actually written ( unit is Byte)

fread:

  1. size_t fread(void *buffer, size_t size, size_t count, FILE *stream);  
  2. -- buffer: pointer to the data block  
  3. -- size: The size of each data, the unit is Byte ( for example: sizeof(int) is 4)  
  4. -- count: the number of data  
  5. -- stream: file pointer  

(1) Calling format: fread(buf, sizeof(buf), 1, fp);
when the read is successful: when the amount of data read is exactly sizeof(buf) Bytes, the return value is 1 (ie count)
                       otherwise The return value is 0 (the amount of data read is less than sizeof(buf))
(2) Call format: fread(buf,1,sizeof(buf),fp);
the return value of successful reading is the actual number of data read back (unit as Byte)

code show as below:

void read_file_by_binary(){

int flag;

FILE *fp;

FILE *fp1;

const char *type="a+";

char buf[20]="it is test\n";

char buffer[200];

fp=fopen(pathname,type);

fwrite(buf,sizeof(buf),1,fp);

fclose(fp);

fp1=fopen(pathname,type);

flag=fread(buffer,1,sizeof(buffer),fp1);

printf("%ld,%d",sizeof(buffer),flag);

printf("%s",buffer);

fclose(fp1);

}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324738758&siteId=291194637