How would you implement tail efficiently?

后端 未结 4 675
执笔经年
执笔经年 2020-12-14 20:42

What is the efficient way to implement tail in *NIX? I came up (wrote) with two simple solution, both using kind of circular buffer to load lines into circular structure (ar

4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-14 21:21

    /*This example implements the option n of tail command.*/

    #define _FILE_OFFSET_BITS 64
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define BUFF_SIZE 4096
    
    FILE *openFile(const char *filePath)
    {
      FILE *file;
      file= fopen(filePath, "r");
      if(file == NULL)
      {
        fprintf(stderr,"Error opening file: %s\n",filePath);
        exit(errno);
      }
      return(file);
    }
    
    void printLine(FILE *file, off_t startline)
    {
      int fd;
      fd= fileno(file);
      int nread;
      char buffer[BUFF_SIZE];
      lseek(fd,(startline + 1),SEEK_SET);
      while((nread= read(fd,buffer,BUFF_SIZE)) > 0)
      {
        write(STDOUT_FILENO, buffer, nread);
      }
    }
    
    void walkFile(FILE *file, long nlines)
    {
      off_t fposition;
      fseek(file,0,SEEK_END);
      fposition= ftell(file);
      off_t index= fposition;
      off_t end= fposition;
      long countlines= 0;
      char cbyte;
    
      for(index; index >= 0; index --)
      {
        cbyte= fgetc(file);
        if (cbyte == '\n' && (end - index) > 1)
        {
          countlines ++;
          if(countlines == nlines)
          {
        break;
          }
         }
        fposition--;
        fseek(file,fposition,SEEK_SET);
      }
      printLine(file, fposition);
      fclose(file);
    }
    
    int main(int argc, char *argv[])
    {
      FILE *file;
      file= openFile(argv[2]);
      walkFile(file, atol(argv[1]));
      return 0;
    }
    
    /*Note: take in mind that i not wrote code to parse input options and arguments, neither code to check if the lines number argument is really a number.*/
    

提交回复
热议问题