http://book.51cto.com/art/201303/386678.htm
3.8.1 如何发送磁盘中的文件(1)
发送文件时使用的是3.7节中所介绍的接口。例如:
- ngx_chain_t out;
- out.buf = b;
- out.next = NULL;
- return ngx_http_output_filter(r, &out);
两者不同的地方在于如何设置ngx_buf_t缓冲区。在3.2.5节中介绍过,ngx_buf_t有一个标志位in_file,将in_file置为1就表示这次ngx_buf_t缓冲区发送的是文件而不是内存。调用ngx_http_output_filter后,若Nginx检测到in_file为1,将会从ngx_buf_t缓冲区中的file成员处获取实际的文件。file的类型是ngx_file_t,下面看一下ngx_file_t的结构。
- typedef struct ngx_file_s ngx_file_t;
- struct ngx_file_s {
- //文件句柄描述符
- ngx_fd_t fd;
- //文件名称
- ngx_str_t name;
- //文件大小等资源信息,实际就是Linux系统定义的stat结构
- ngx_file_info_t info;
- /*该偏移量告诉Nginx现在处理到文件何处了,一般不用设置它,Nginx框架会根据当前发送状态设置它*/
- off_t offset;
- //当前文件系统偏移量,一般不用设置它,同样由Nginx框架设置
- off_t sys_offset;
- //日志对象,相关的日志会输出到log指定的日志文件中
- ngx_log_t *log;
- //目前未使用
- unsigned valid_info:1;
- //与配置文件中的directio配置项相对应,在发送大文件时可以设为1
- unsigned directio:1;
- };
fd是打开文件的句柄描述符,打开文件这一步需要用户自己来做。Nginx简单封装了一个宏用来代替open系统的调用,如下所示。
- #define ngx_open_file(name, mode, create, access) \
- open((const char *) name, mode|create, access)
实际上,ngx_open_file与open方法的区别不大,ngx_open_file返回的是Linux系统的文件句柄。对于打开文件的标志位,Nginx也定义了以下几个宏来加以封装。
- #define NGX_FILE_RDONLY O_RDONLY
- #define NGX_FILE_WRONLY O_WRONLY
- #define NGX_FILE_RDWR O_RDWR
- #define NGX_FILE_CREATE_OR_OPEN O_CREAT
- #define NGX_FILE_OPEN 0
- #define NGX_FILE_TRUNCATE O_CREAT|O_TRUNC
- #define NGX_FILE_APPEND O_WRONLY|O_APPEND
- #define NGX_FILE_NONBLOCK O_NONBLOCK
- #define NGX_FILE_DEFAULT_ACCESS 0644
- #define NGX_FILE_OWNER_ACCESS 0600