APUE 3e 部分习题整理 Chap5

APUE 3e 部分习题整理 Chap5

Chapter5

5.1 使用setvbuf实现setbuf

根据 man手册 setbuf(FILE *stream, char *buf) 中如果指定 buf == NULL 那么就是关闭 buf,  如果指定 buf != NULL 那么就创建一个 BUFSIZ 大小的 buffer 供流使用 因而实现的代码如下

// 5.1 Answer
void mysetbuf(FILE *stream, char *buf) {
    setvbuf(stream, buf, buf ? _IOFBF :_IONBF, BUFSIZ);
}

5.5 对标准I/O流如何使用fsync

fsync 需要的参数是 fd 描述符,因而只要能获得文件 FILE 结构体的 fd 值即可

这里一定要注意: 在使用fsync的时候一定要fflush流的缓冲区 fsync是将内核里的缓存数据写入磁盘/文件, 而对于打开的文件

是全缓冲的,也就是说没有写满IO缓冲区之前是不会去写入内核缓冲区的 因而就算调用fsync也没有什么用呢~ 你需要先把数据从 IO buffer中写入内核buffer然后fsync才有用 所以一定要fflush

 

P.S.:天真的窝以为这题只是考察能不能把FILE结构体给找到,并拿出来相应的fileno,没想到我太天真了=o=

#include<stdio.h>
#include<unistd.h>

int fsync_stream(FILE *stream);
int main(void) {
 FILE *fp = fopen("demo.txt", "w+");
 fprintf(fp, "I love Shana");
 fsync_stream(fp);
 while(1);
 return 0;
}

int fsync_stream(FILE *stream) {
 fflush(fp); // Without this, the demo.txt will leave empty when program stopped by Ctrl-C
 return fsync(stream->_fileno);
}

FILE 结构体中的 _fileno就是相应的文件描述符

5.6 题略 (Page 141[175英文版])

虽然看glibc的源码暂时没有看懂,不过查到的资料包括http://c-faq.com/stdio/stdinflush2.html文档都说明了这个事实就是 scanf, getchar, gets, fgets在调用的时候都会flush buffer

5.7 用FreeBSD上的funopen实现fmemopen

代码暂略

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

12 − three =

This site uses Akismet to reduce spam. Learn how your comment data is processed.