Summary File operation functions (2)-C Language

Source: Internet
Author: User

Formatted read/write:

# Include

Int printf (const char * format,...); // equivalent to fprintf (stdout, format ,...);

Int scanf (const char * format ,...);

Int fprintf (FILE * stream, const char * format,...); // The intermediate parameter is the format of the written FILE.

Int fscanf (FILE * stream, const char * format ,...); // The format in the middle is read from the file

Int sprintf (char * str, const char * format,...); // eg: sprintf (buf, "the string is; % s", str );

Int sscanf (char * str, const char * format ,...); // Formatted and read from a string

Writes formatted strings starting with f to the file stream.

Writes formatted strings starting with s to str.

The kernel maintains an open file record table for each process. The file descriptor is a small positive INTEGER (0-1023), which represents a record table, through file descriptors and a set of file operation functions based on file descriptors, you can read, write, create, and delete files. Common file descriptor-based functions include open, creat, close, read, write, and ftruncate) lseek, fsync, fstat, fchmod, flock, fcntl, and dup), dup2, select, and ioctl. File Operations Based on file descriptors are not ansi c functions.

After opening a file, this type of function will convert the file name to the currently least available file descriptor. 0, 1, 2 are occupied!

# Include // Header file

# Include

# Include // Common flags include O_RDONLY, O_WRONLY, and O_CREAT, which are read-only and write-only.

Int open (const char * pathname, int flags); // file name Opening Method

Int open (const char * pathname, int flags, mode_t mode); // permission for opening a file name

Open (pathname, O_CREAT | O_WRONLY, mode; // create and read files

-1 is returned when an open () function error occurs. The related parameters are as follows:

Both flags and mode are the compositing values of a group of masks. flags indicates the mode for opening or creating a file, and mode indicates the file access permission.


Read and Write files through file descriptors

Function prototype:

# Include

Ssize_t read (int fd, void * buf, size_t count); // file description Word Buffer length data read from file to buf

Ssize_t write (int fd, const void * buf, size_t count); // string in buf is written to the file

Fd = 1. write indicates that the file is output from the standard output stream. fd = 0. read indicates that the file is read from the standard input stream to the buf.

For the read and write Functions, error-1 is returned. After reading is complete, 0 is returned. In other cases, the number of reads and writes (the number of bytes) is returned ).

Function for getting file information:

# Include

Int stat (const char * file_name, struct stat * buf); // obtain the file information through the file name and save it in the struct stat referred to by buf.

Int fstat (int fd, struct stat * buf); // file description word stat struct pointer

Returned value: if the execution is successful, 0 is returned. If the execution fails,-1 is returned. The error code is stored in errno (you need to include )

Use man stat to find the object information contained in the struct.

Currently, the select function is mostly used for function read/write dynamic listening:

# Include

# Include

Int select (int maxfd, fd_set * readset, fd_set * writeset, fd_set * predictionset, const struct timeval * timeout );

Return: the number of vertices in the ready description. Value 0 indicates timeout, and value-1 indicates an error.

Parameter description:

Maxfd: the largest file descriptor (the value should be the largest file descriptor word + 1)

Readset: a set of Descriptor words for Kernel read Operations

Writeset: a set of Descriptor words for Kernel write operations

Predictionset: a set of Descriptor words for Kernel exception operations

Timeout: How long does it take to wait for the descriptor to be ready. NULL indicates waiting forever. A fixed value indicates waiting for a fixed time. 0 indicates not waiting at all. Return immediately after checking the description.

Readset, writeset, and predictionset are all fd_set sets. Perform the following operations on the set:

Void FD_ZERO (fd_set * fdset);/* clear all fd */

Void FD_SET (int fd, fd_set * fdset);/* add an fd */Add it to the listener set

Void FD_CLR (int fd, fd_set * fdset);/* Delete An fd */

Int FD_ISSET (int fd, fd_set * fdset);/* determines whether an fd is 1 */

Generally, before using the select function, you must first use FD_ZERO and FD_SET to initialize the file descriptor set. When using the select function, the changes of each descriptor in the set are tested based on the set time, if a descriptor changes, the descriptor is changed to 1. The set change indicates that the descriptor is not blocked currently. You can use FD_ISSET cyclically to test the descriptor set and test whether the descriptor is 1. This is a better understanding. After the related file descriptor is executed, use FD_CLR to clear the descriptor set.

In addition, the timeout in the select function is a pointer of the struct timeval type. The struct is as follows:

Struct timeval

{

Long TV _sec;/* second * // second

Long TV _usec;/* microsecond * // microsecond

};

Convert a file name descriptor to a file pointer (mostly for pipelines that cannot be opened with fopen ):

Fdopen function related functions: fopen, open, fclose

# Include

FILE * fdopen (int fildes, const char * mode );

Function Description: fdopen obtains an existing file descriptor (we may obtain the descriptor from o p e n, d u p, d u p 2, f c n t l or p I p e function to get this file descriptor) and combine a standard I/O Stream with this descriptor.

This function is commonly used to obtain descriptors by the function of creating MPs queues and network communication channels.

Because these special types of files cannot be opened using the standard I/O fopen function, you must first call the dedicated function of the device to obtain a file descriptor, then, f d o p e n is used to combine a standard I/O stream with the descriptor.

Fdopen () converts the file description of fildes to the corresponding file pointer and returns the result. The mode string represents the stream format of the file pointer, which must be the same as the read/write mode of the original file description. Mode has the following types of strings: r. To open a read-only file, the file must exist. W. Open and write only the file. If the file exists, the file length is 0, indicating that the file content will disappear. If the file does not exist, the file is created. A. Open and write-only files as an attachment. If the file does not exist, the file will be created. If the file exists, the written data will be added to the end of the file, that is, the original content of the file will be retained.

For f d o p e n, t y p e parameters are slightly different. Because the descriptor has been opened, f d o p e n indicates that the file is not truncated when writing. (For example, if the descriptor was originally opened by the o p e n function and the file already exists, the O _ t r u n c mark of the descriptor determines whether to trunate the file. The f d o p e n function cannot shorten any file it opens for writing. ) In addition, the standard I/O addition method cannot be used to create the file (because if a descriptor references a file, the file must already exist ).



Next, I will post the code used to contact the function. The first one is to imitate the linux ls-l function:

//File Name: myls.c#include 
 
  #include 
  
   #include 
   
    #include 
    
     #include 
     
      #include 
      
       #include 
       
        #include 
        
         #include 
         
          void mode_to_str(mode_t md,char *str);void format(char *time);int main(int argc,char *argv[]){char *time;char str_mode[11];DIR *Pdir;struct stat mystat;struct dirent *myent;if(argc==1){Pdir=opendir(".");}else{Pdir=opendir(argv[1]);}if(Pdir==NULL){perror("open fail:");exit(-1);}printf("no,mode,uid,gid,");while((myent = readdir(Pdir))!=NULL){memset(&mystat,0,sizeof(mystat));stat(myent->d_name,&mystat);memset(str_mode,0,11);mode_to_str(mystat.st_mode,str_mode);time=ctime(&mystat.st_atime);time=format(time);//printf("%s\t",myent->d_name);//printf("size=%d,type=%c,name=%s\n",myent->d_reclen,myent->d_type,myent->d_name);printf("%10s. %2d %8d %8d %5d %s %s\n",str_mode,mystat.st_nlink,getpwuid(mystat.st_uid)->pw_name,getgrgid(mystat.st_gid)->gr_name,mystat.st_size,time,myent->d_name);}return 0;}void mode_to_str(mode_t md,char *str){strcpy(str,"----------");if(S_ISDIR(md)){str[0]='d';}if(md & S_IRUSR){str[1]='r';}if(md & S_IWUSR){str[2]='w';}if(md & S_IXUSR){str[3]='x';}if(md & S_IRGRP){str[4]='r';}if(md & S_IWGRP){str[5]='w';}if(md & S_IXGRP){str[6]='x';}if(md & S_IROTH){str[7]='r';}if(md & S_IWOTH){str[8]='w';}if(md & S_IXOTH){str[9]='x';}}char *format(char *time){char *p;while((*time)!=' '){time++;}p=time;while((*p)!=':'){p++;}p=p+3;(*p)='\0';return time;}
         
        
       
      
     
    
   
  
 

Like file operations with standard io streams, pipelines also support file stream modes. The pipeline used to create connections to another process is through the popen and pclose functions.

Function prototype:

# Include

FILE * popen (const char * command, const char * open_mode );

Int pclose (FILE * fp );

Function popen (): allows a program to start another program as a new process, and can pass data to it or receive data through it. The command string is the name of the program to run. Open_mode must be "r" or "w ". If open_mode is "r", the output of the called program can be used by the calling program. The calling program uses the FILE * FILE stream pointer returned by the popen function, you can use common stdio library functions (such as fread) to read the output of the called program. If open_mode is "w", the calling program can use fwrite to send data to the called program, the called program can read the data on its own standard input.

Function pclose (): When the process started with popen ends, we can use the pclose function to close the file stream associated with it.

Example1: Read/etc/profile content from the standard pipeline stream # include
 
  
Int main () {FILE * fp = popen ("cat/etc/profile", "r"); char buf [512] = {0}; while (fgets (buf, sizeof (buf), fp) {puts (buf);} pclose (fp); return 0 ;}
 

Example2: count the number of buf words written to the standard pipeline stream # include
 
  
Int main () {char buf [] = {"aaa bbb ccc ddd eee fff ggg hhh"}; FILE * fp = popen ("wc-w", "w "); fwrite (buf, sizeof (buf), 1, fp); pclose (fp); return 0 ;}
 

Pipeline function prototype:

# Include

Int pipe (int fds [2]);

The pipeline is represented by a pair of file descriptors in the program. One of the file descriptors has the readable attribute and the other has the writable attribute. Fds [0] is read, and fds [1] is write.

The pipe function is used to create an unknown pipeline. If the pipeline is successful, fds [0] Stores readable file descriptors, fds [1] Stores writable file descriptors, and the function returns 0; otherwise,-1 is returned.

After pipe is called to obtain the opened file descriptor, a process can read data from fds [0], and another process can write data to fds [1. Of course, the two processes must have an inheritance relationship to inherit the opened file descriptor.

Unlike real physical files, the MPs queue is not persistent. After the two processes are terminated, the MPs queue automatically disappears.

Example: Create a parent-child process, create an unknown pipeline, and write the parent-child read # include
 
  
# Include
  
   
# Include
   
    
Int main () {int fds [2] = {0}; pipe (fds); char szBuf [32] = {'\ 0'}; if (fork () = 0) {// indicates the sub-process close (fds [1]); // The sub-process closes write sleep (2); // make sure that the parent process has time to close the read, in addition, if (read (fds [0], szBuf, sizeof (szBuf)> 0) puts (buf); close (fds [0]); // sub-close read exit (0);} else {// indicates that the parent process is close (fds [0]); // The parent closes read write (fds [1], "hello", 6); waitpid (-1, NULL, 0); // read/write (fds [1], "world", 6 ); // at this time, the "disconnected Pipeline" will appear because the sub-read has closed close (fds [1]); // The parent closes the write exit (0 );} return 0 ;}
   
  
 

Use the two-person chat program of the pipeline:

# Include
 
  
# Include
  
   
# Include
   
    
# Include
    
     
# Include
     
      
# Include
      
        # Include
       
         # Include
        
          # Include
         
           Void my_handler (int num) {wait (NULL); exit (0);} int main (int argc, char * argv []) {int fd_w, fd_r; pid_t pid; char buf [1024]; // int * stat = NULL; fd_w = open ("1to2. fifo ", O_WRONLY); fd_r = open (" 2to1. fifo ", O_RDONLY); if (pid = (fork ()> 0) // father send {close (fd_r); signal (17, my_handler ); // 17 signal to process yourself; FILE * fd = fdopen (fd_w, "w"); if (fd = NULL) {perror ("1to2 write failed! \ N ");} while (memset (buf, 1024), fgets (buf, stdin )! = NULL) {fprintf (fd, "trudream: % s", buf); // format the input fflush (fd);} fprintf (fd, "bye \ n "); kill (pid, 2); // kill the son close (fd_w); while (1); // waitpid (-1, NULL, WNOHANG ); // wait (NULL);} else {close (fd_w); while (memset (buf, 1024), read (fd_r, buf,)> 0) {write (1, buf, strlen (buf); while (strncmp (buf, "bye", 3) = 0) {exit (0) ;}} close (fd_r );} return 0 ;}
         
        
       
      
     
    
   
  
 

# Include
 
  
# Include
  
   
# Include
   
    
# Include
    
     
# Include
     
      
# Include
      
        # Include
       
         # Include
        
          # Include
         
           Void handler (int num) {wait (NULL); exit (0);} int main (int argc, char * argv []) {int fd_w, fd_r; pid_t pid; char buf [1024]; fd_r = open ("1to2. fifo ", O_RDONLY); fd_w = open (" 2to1. fifo ", O_WRONLY); if (pid = fork ()> 0) // father receive {close (fd_w); signal (17, handler ); while (memset (buf, 1024), read (fd_r, buf,)> 0) {write (1, buf, strlen (buf); if (strncmp (buf, "bye", 3) = 0) {break;} close (fd_r); kill (pid, 2); while (1); // waitpid (-1, N ULL, WNOHANG); // wait (NULL);} else {close (fd_r); FILE * fd = fdopen (fd_w, "w"); if (fd = NULL) {perror ("2to1 write failed! \ N ");} while (memset (buf, 1024), fgets (buf, stdin )! = NULL) {fprintf (fd, "smile: % s", buf); // format the input fflush (fd);} fprintf (fd, "bye \ n"); close (fd_w);} return 0 ;}
         
        
       
      
     
    
   
  
 

Multi-User client server chat:

Server Design: Permanent server channel (the server only reads data from the Channel)> Create a set> Add the server channel descriptor to the set to determine whether to go online # Read the process number when going online, get the corresponding channel name, get the file descriptor of the read/write Channel # forcibly close the process when the client port is full, delete the channel> Add set listener changes> loop FD_ISSET ()

Changes in each read pipeline. If the changes, the pipeline information is read.

> Determine whether the first three characters of the MPs queue are the bye end strings. If yes, deprecate the MPs Queue (close the process, close the read/write MPs queue, and clear the-1 client list)

> NO. Send the MPs queue information to other MPs queues. (the listener sends messages for each non-1 Non-1 in the client)


// File Name: sever. c # include
 
  
# Include
  
   
# Include
   
    
# Include
    
     
# Include
     
      
# Include
      
        # Include
       
         # Include
        
          # Include
         
           # Include
          
            # Define NUM 500 typedef struct tag {int s_read; int s_write;} CLIENT_NODE; int main (int argc, char * argv []) {if (argc! = 2) {printf ("No Pipename! \ N "); exit (-1) ;}int client_pid; // The client process idint fd_read, fd_write; // records the pipeline file descriptor char buf [1024]; char writable o_write [128]; // The write end here is the client's read end, used to accept the pipeline file name created by the client char writable o_read [128]; // The read end is the client write client CLIENT_NODE client_infor [NUM]; // used to place the int fd_sever for each chat client read/write pipeline; // The MPs queue name memset (client_infor,-1, sizeof (client_infor); fd_sever = open (argv [1], O_RDONLY); // read-only development server pipeline fd_set read_set, ready_set; // select set FD_ZERO (& read_set ); FD_SET (fd_sever, & read_set ); // Add the collection struct timeval tm; while (1) {tm. TV _sec = 0; tm. TV _usec = 1000; // 1 subtle ready_set = read_set; select (1024, & ready_set, NULL, NULL, & tm); // round-robin if (FD_ISSET (fd_sever, & ready_set )) // someone connects to the server and goes online {memset (buf, 1024); if (read (fd_sever, buf,) = 0) {continue;} client_pid = atoi (buf ); // obtain the process number printf ("client % d on! \ N ", client_pid); sprintf (export o_read," % d_write.fifo ", client_pid); sprintf (export o_write," % d_read.fifo ", client_pid); fd_write = open ); fd_read = open (export o_read, O_RDONLY); //> ???????? Int index; for (index = 0; index
           
            

Client design: Permanent server pipeline (the client only writes data to this channel)> read/write dual-channel (use a unique process ID to create two channels)> write a unique process ID to the server pipeline> open dual channel conversion to process descriptor> fork () Create Parent and Child processes> parent process is responsible for writing information (used to kill Child processes (), unlink () delete the channel file, use signal (), recycle sub-processes, exit () to commit suicide)


// File Name: myclient. c # include
             
              
# Include
              
               
# Include
               
                
# Include
                
                 
# Include
                 
                  
# Include
                  
                    # Include
                   
                     # Include
                    
                      # Include
                     
                       # Include
                      
                        Void handler (int num) {wait (NULL); exit (-1);} int main (int argc, char * argv []) {if (argc! = 2) {printf ("Not Input PipeName! \ N "); exit (-1);} int fd_sever; // server pipeline identifier int fd_read, fd_write; // read/write pipeline identifier char buf [1024]; char character o_write [128] = ""; char character o_read [128] = ""; int pid; fd_sever = open (argv [1], O_WRONLY ); // write information to the server pipeline sprintf (export o_read, "% d_read.fifo", getpid (); sprintf (export o_write, "% d_write.fifo", getpid (); mkfifo (export o_read, 0666); mkfifo (writable o_write, 0666); FILE * fp = fdopen (fd_sever, "w"); if (fp = NULL) {perror ("sever link failed! \ N "); exit (-1);} fprintf (fp," % d ", getpid (); // prompt that the server is online, and tell the server's own read/write pipeline fflush (fp) through the process number; fd_read = open (export o_read, O_RDONLY); fd_write = open (export o_write, O_WRONLY ); // file printf ("% d begin talk! ", Getpid (); if (pid = fork ()> 0) // The parent process writes {close (fd_read); signal (17, handler ); // format the input FILE * fdw = fdopen (fd_write, "w"); if (fdw = NULL) {printf ("the fd_write is failed \ n "); exit (-1);} while (memset (buf, 1024), fgets (buf, stdin )! = NULL) {fprintf (fdw, "from % d: % s", getpid (), buf); fflush (fdw);} fprintf (fdw, "% s ", "bye"); fflush (fdw); printf ("kill child! \ N "); close (fd_write); kill (pid, 9); unlink (same o_read); unlink (same o_write); while (1);} else {close (fd_write ); while (memset (buf, 1024), read (fd_read, buf,)> 0) {fflush (stdout); write (1, buf, strlen (buf )); fflush (stdout);} close (fd_read);} return 0 ;}
                      
                     
                    
                   
                  
                 
                
               
              
             



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.