文件描述符
对于内核而言,所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或创建 个新文件时, 内核向进程返回一个文件描述符。当读、写一个文件时,使用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write.
按照馈例,UNIX系统shel把文件描述符0与进程的标准输入关联,文件描述符1与标准输出关联文件描述符2与标准错误关联。
文件操作
-
open()
用来打开和创建 一个 文件或设备,返回值为文件描述符
int open(const char *pathname, int flags);参数 flags : O_RDONLY, O_WRONLY 或 O_RDWR
int open(const char *pathname, int flags, mode_t mode);参数 flags :O_CREAT、O_TRUNC
-
close()
关闭一个文件描述符
int close(int fd);
-
read()
read() 从文件描述符 fd 中读取 count 字节的数据并放入从 buf 开始的缓冲区中,如果 count 为零,read()返回0,不执行其他任何操作,发生错误时返回-1,并置 errno 为相应值,> 0表示实际读取的字节数。
ssize_t read(int fd, void *buf, size_t count);
-
write()
向文件描述符fd 所引用的文件中写入从buf开始的缓冲区中count字节的数据.
ssize_t write(int fd, const void *buf, size_t count);
-
lseek()
将与文件描述符fd相关联的打开文件的offse重新定位到whence。(SEEK_SET、SEEK_CUR、SEEK_END)
off_t lseek(int fd, off_t offset, int whence);
-
dup()/dup2()
复制一个现有的文件描述符。
int dup(int fd);
int dup2(int fd, int fd2);
原子操作
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define BUF_SIZE 10
void main (void) {
int fd = open("test.txt", O_RDONLY);
int fd2 = open("test2.txt", O_WRONLY);
if (fd == -1){
perror("open");
exit(1);
}
printf("open ok.");
while (1){
char buf[BUF_SIZE+1];
memset(buf, 0x00, sizeof(buf));
int r = read(fd, buf, BUF_SIZE);
if (r <= 0){
break;
}
write(fd2, buf, r);
printf("%s", buf);
fflush(stdout);
sleep(1);
}
close(fd);
close(fd2);
}
目录操作
- 打开目录:
DIR *opendir(const char *name);
- 读取目录内容:
struct dirent *readdir(DIR *dirp);
- 关闭目录:
int closedir(DIR *dirp);
文件的控制fcntl()
非阻塞:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
void set_flg(int fd, int flag) {
int flags = fcntl(fd, F_GETFL, 0);
flags |= flag;
fcntl(fd, F_SETFL, flags);
}
int main( void ) {
char buf[1024] = {};
write(1, "input > ", 8);
set_flg(0, O_NONBLOCK);
int ret = read(0, buf, 1024);
if ( ret == 0 ) {
printf("read EOF\n");
return 0;
}
if ( ret == -1 ) {
perror("read");
return 0;
}
printf("buf=[%s]\n", buf);
}
文件锁
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main( void ) {
int fd = open("test.txt", O_RDWR);
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if ( fcntl(fd, F_SETLKW, &lock) == 0 ) {
printf("lock ok\n");
} else {
perror("lock err\n");
exit(0);
}
printf("enter any key to unlock\n");
getchar();
lock.l_type = F_UNLCK;
if ( fcntl(fd, F_SETLKW, &lock) == 0 ) {
printf(" unlock ok\n");
} else {
perror("unlock");
exit(0);
}
for ( ; ; ) {
printf(".");
fflush(stdout);
sleep(1);
}
close(fd);
}
静态库:对.o
文件打包
[root@localhost ~]# gcc add.c -c
[root@localhost ~]# gcc sub.c -c
[root@localhost ~]# ar rcs libmymath.a add.o sub.o
[root@localhost ~]# gcc main.c -L. -lmymath
[root@localhost ~]# ./a.out
动态库:
[root@localhost ~]# gcc -fPIC -o libmymath.so sub.c add.c -shared
[root@localhost ~]# mv libmymath.* /user/lib64/
[root@localhost ~]# gcc main.c -lmymath
[root@localhost ~]# ./a.out