今天刚学完基本的文件操作,特地记录一些心得。
umask
umask
是一个系统变量,在创建文件的时候起掩码的作用:假设要创建的文件权限为 mode
,那么最终实际得到的文件权限为 mode & ~umask
。可以反过来理解为,umask 中看上去“允许”的权限,实际上是禁止的。例如,在 umask
为 001 的时候,创建的文件无论如何都不会将执行权限赋给其他用户。可以使用 mode_t getumask (void)
和 mode_t umask (mode t mask)
函数分别读写 umask
。
off_t lseek(int fildes, off_t offset, int whence) 和 int fseek (FILE* stream, long int offset, int whence)
值得注意的是,如果想要从文件末尾向回跳过,例如,5 个字节(whence
设为 SEEK_END
),offset
应该设为 -5L。
int fflush(FILE* stream)
网上很多人在问如何清空标准输入流。有人说用 fflush(stdin)
,实际上这只在 Windows 下有效(微软自己扩展的)。在 Linux 下达到此目的最简单的办法就是强制让标准输入流认为已经读到了缓冲区的末尾:stdin->_IO_read_ptr = stdin->_IO_read_end
。
int fgetc(FILE* stream)、int getc(FILE* stream) 和 int getchar(void)
为什么这些读取字符的函数返回值的类型都是 int
而非 char
?因为如果不这样,就无法返回表示文件末尾的 EOF
(-1)。
char* fgets(char* s, int n, FILE* stream) 和 char* gets(char* s)
用这两个函数读取一行文本不可靠,因为你永远不可能知道下一行将有多少字符。推荐使用 ssize_t getline (char** lineptr, size_t* n, FILE* stream)
。
int sprintf(char* s, const char* format, ...) 和 int snprintf(char* s, size t size, const char* template, ...)
同样由于无法预知将会产生多少字符而不太可靠。推荐使用 int asprintf(char** ptr, const char* template, ...)
。
int unlink(const char* filename)、int rmdir(const char* filename) 和 int remove(const char* filename)
在调用这三个函数之一后,文件并不一定会马上删掉,而是要等到所有打开此文件的线程都关闭文件之后。这可以作为一种管理临时文件的编程技巧:创建临时文件后立即调用删除函数。
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off)
off
必须为分页大小的整数倍,否则会映射失败。分页大小可通过 int getpagesize(void)
得到,这通常是一个很大的数字,所以 off
一般设为 0。