ngx——如何读写文件

1. 读文件

1.1 读配置文件

1.1.1 打开文件

除了 获得文件描述符,还获得 文件信息 struct stat,这些信息都存放在 ngx_file_t
并使用 ngx_buf_t 用于缓存文件内容
而 ngx_file_t 和 ngx_buf_t 组合成 ngx_conf_file_t

   157 char *
   158 ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
   159 {
   180         fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0       );
   193         if (ngx_fd_info(fd, &cf->conf_file->file.info) == NGX_FILE_ERROR) {
   194             ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
   195                           ngx_fd_info_n " \"%s\" failed", filename->data);
   196         }
   198         cf->conf_file->buffer = &buf;
   200         buf.start = ngx_alloc(NGX_CONF_BUFFER, cf->log);
   201         if (buf.start == NULL) {
   202             goto failed;
   203         }
   204
   205         buf.pos = buf.start;
   206         buf.last = buf.start;
   207         buf.end = buf.last + NGX_CONF_BUFFER;
   208         buf.temporary = 1;
   209
   210         cf->conf_file->file.fd = fd;
   211         cf->conf_file->file.name.len = filename->len;
   212         cf->conf_file->file.name.data = filename->data;
   213         cf->conf_file->file.offset = 0;
   214         cf->conf_file->file.log = cf->log;
   215         cf->conf_file->line = 1;
   242     for ( ;; ) {
   243         rc = ngx_conf_read_token(cf);
                ...
  324     }

   333         if (cf->conf_file->buffer->start) {
   334             ngx_free(cf->conf_file->buffer->start);
   335         }
   336
   337         if (ngx_close_file(fd) == NGX_FILE_ERROR) {
   341             rc = NGX_ERROR;
   342         }

涉及对象

 17 typedef struct stat              ngx_file_info_t;

 16 struct ngx_file_s {
 17     ngx_fd_t                   fd;
 18     ngx_str_t                  name;
 19     ngx_file_info_t            info;
 20
 21     off_t                      offset;
 22     off_t                      sys_offset;
 23
 24     ngx_log_t                 *log;
 36
 37     unsigned                   valid_info:1;
 38     unsigned                   directio:1;
 39 };

 98 typedef struct {
 99     ngx_file_t            file;
100     ngx_buf_t            *buffer;
101     ngx_buf_t            *dump;
102     ngx_uint_t            line;
103 } ngx_conf_file_t;

 20 struct ngx_buf_s {
 21     u_char          *pos;
 22     u_char          *last;
 23     off_t            file_pos;
 24     off_t            file_last;
 25
 26     u_char          *start;         /* start of buffer */
 27     u_char          *end;           /* end of buffer */
        ...

1.1.2 读文件

ngx使用有限缓存,分析无限数据。

   502 static ngx_int_t
   503 ngx_conf_read_token(ngx_conf_t *cf)
   504 {
   523     cf->args->nelts = 0;
   524     b = cf->conf_file->buffer;
   525     dump = cf->conf_file->dump;
   526     start = b->pos;
   527     start_line = cf->conf_file->line;
   528
   529     file_size = ngx_file_size(&cf->conf_file->file.info);
   530
   531     for ( ;; ) {
   532
   533         if (b->pos >= b->last) {  // 缓存数据已扫描完毕
   534
   535             if (cf->conf_file->file.offset >= file_size) { // 文件读取完毕
   552                 return NGX_CONF_FILE_DONE;
   553             } 
   555             len = b->pos - start;  // 剩余未分析数据(由于不完整导致)
   556
   557             if (len == NGX_CONF_BUFFER) {  // 不完整数据过长
   558                 cf->conf_file->line = start_line;
   576                 return NGX_ERROR;
   577             }
   579             if (len) {   // 将不完整数据移动到b->start
   580                 ngx_memmove(b->start, start, len);
   581             }
   583             size = (ssize_t) (file_size - cf->conf_file->file.offset); // 文件剩余大小
   584
   585             if (size > b->end - (b->start + len)) { // 保证读取 缓存能容纳
   586                 size = b->end - (b->start + len);
   587             }
   589             n = ngx_read_file(&cf->conf_file->file, b->start + len, size,
   590                               cf->conf_file->file.offset); // 读取
   596             if (n != size) {
   601                 return NGX_ERROR;
   602             }
   604             b->pos = b->start + len;  // 移动扫描指针
   605             b->last = b->pos + n;  // 移动到未扫描数据末尾
   606             start = b->start;   // 移动分析数据指针
   611         }
            // 分析数据,移动 b->pos , start
              ...
   816     }
   817 }

posted on 2022-04-28 15:15  开心种树  阅读(213)  评论(0编辑  收藏  举报