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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?