Linux下文件的通用操作方法
在Linux下用文件描述符来表示设备文件和普通文件。文件描述符是一个整型的数据,所有对文件的操作都通过文件描述符实现。文件描述符是文件系统中链接用户空间和内核空间的枢纽。
1、open()和creat()
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
返回值:文件描述符fd
pathname:文件路径
flags:打开后文件的操作方式
O_RDONLY:只读
O_WRONIY:只写
O_RDWR:读写
O_APPEND:写操作追加到文件的尾端
O_CREAT:如果不存在则创建它。当使用此选项的时,第三个参数mode需要同时设定,用来说明新文件的权限
O_EXCL:查看文件是否存在。如果同时指定O_CREAT,而文件已经存在,会返回错误。用这种方法安全地打开一个文件
O_TRUNC:将文件截断为0
mode:用于表示打开文件的权限
S_IRWXU:用户(所有者)有读写和执行的权限
S_IRUSR:用户有读权限
S_IWUSR:用户有写权限
S_IXUSR:用户有执行权限
S_IRWXP:用户组有读写和执行权限
S_IRGRP:用户组有读权限
S_IWGRP:用户组有写权限
S_IXGRP:用户组有执行权限
S_IRWXO:其他用户有读写和执行权限
S_IROTH:其他用户有读权限
S_IWOTH:其他用户有写权限
S_IXOTH:其他用户有执行权限
2、close()
文件打开之后必须关闭。
#include <unistd.h>
int close(int fd);
返回值:成功返回0;失败返回-1,通常不检查返回值
fd:文件描述符,通常open()或creat()的返回值
3、read()
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
返回值:如果读取成功,返回读取的字节数,有错返回-1
fd:文件描述符,通常open()或creat()的返回值
buf:要写入数据的指针
count:表示要读取的字节数量,通常用这个变量来表示缓冲区的大小
1 /* fileOpen.c*/
2 /* 文件打开*/
3
4 #include<stdio.h>
5
6 #include<sys/types.h>
7 #include<sys/stat.h>
8 #include<fcntl.h>
9 #include<unistd.h>//read()
10
11
12 int main(){
13 int fd = -1;
14 char fileName[] = "test.txt";
15 ssize_t size = -1;
16 char buf[10];
17 int i;
18
19 fd = open(fileName, O_RDWR);
20
21 if(fd == -1){
22 printf("Open file %s failure!\nfd:%d\n", fileName, fd);
23 }else{
24 printf("Open file %s success!\nfd:%d\n", fileName, fd);
25 }
26
27 while(size){
28 size = read(fd, buf, 10);
29 if(size == -1){
30 close(fd);
31 printf("read file error occurs\n");
32 return -1;
33 }else{
34 if(size > 0){
35 printf("read %d bytes:", size);
36 printf("\"");
37 for(i = 0; i < size; i++){
38 printf("%c",*(buf+i));
39 }
40 printf("\"\n");
41 }else{
42 printf("reach the end of file\n");
43 }
44 }
45 }
46 close(fd);
47 return 0;
48 }
4、write()
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
返回值:如果写入成功,返回写入的字节数,有错返回-1
fd:文件描述符,通常open()或creat()的返回值
buf:是一个指针,指向缓冲区地址的开始位置
count:表示要写入的字节数量,通常用这个变量来表示缓冲区的大小
5、lseek() 设置文件偏移量的位置
#include <sys/types>
#include <unistd.h>
off_t lseek(int filedes, off_t offset, int whence);
返回值:如果成功,返回新的文件偏移量
filedes:文件描述符
offset:重新设定文件的偏移量
whence:操作模式
SEEK_SET:offset为相对文件开始处的值
SEEK_CUR:offset为相对当前位置的值
SEEK_END:offset为相对文件结束处的值,即文件长度-offset
6、stat()、fstat()、lstat() 获取文件状态stat
struct stat {
dev_t st_dev; /* 此文件所处设备的设备ID号*/
ino_t st_ino; /* inode数值*/
mode_t st_mode; /* 保护设置*/
nlink_t st_nlink; /* 硬连接数*/
uid_t st_uid; /* 文件所有者的ID*/
gid_t st_gid; /*文件所有者的组ID*/
dev_t st_rdev; /* 设备ID*/
off_t st_size; /* 以字节记的大小*/
blksize_t st_blksize; /* 文件系统的块大小*/
blkcnt_t st_blocks; /* 占用块的数量*/
time_t st_atime; /* 最后访问时间*/
time_t st_mtime; /* 最后修改时间*/
time_t st_ctime; /* 最后状态改变时间*/
};
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *path, struct stat *buf); int fstat(int filedes, struct stat *buf); int stat(const char *path, struct stat *buf);
返回值:执行成功返回0;出错返回-1
path:文件的路径
filedes:文件描述符
buf:指向struct stat 的指针
7mmap()、munmap() 文件空间映射函数
mmap()函数用来将文件或者空间设备映射到内存中,可以通过对映射后的内存空间存取来获得与存取文件一致的控制方式,不必再使用read()、write()函数。简单的说此函数就是将文件映射到内存中的某一段,内存比磁盘快些。映射到的内存并不占用空间,仅仅占用一段地址空间。
#include <sys/mman.h> void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
返回值:映射成功返回映射到的内存地址,失败返回(void *)-1。
start:用户指定要映射到的地址,通常为NULL
length:映射数据的长度
fd:需要映射的文件的文件描述符
offset:文件内偏移量
prot:映射区保护方式,是一个组合值
PROT_EXEC 可执行
PROT_READ 可读
PROT_WRITE 可写
PROT_NONE 不可存取
flags:用于设定映射对象的类型、选项和是否可以对映射区对象进行操作(读写)。
MAP_FIXED:如果参数start制定地址,而地址无法成功建立映射,则返回失败
MAP_SHARED:共享的映射区域,修改将写到原来的文件中
MAP_PRIVATE:对映射区进行写入操作时会产生一个映射文件的复制
MAP_ANONYNOUS:建立匿名映射。此时忽略fd,不涉及文件
MAP_DENYWRITE:对文件的写操作被禁止
MAP_LOCKED:将映射区域锁定
#include <sys/mman.h> int *munmap(void *start, size_t length)
start:mmap()函数执行成功的返回值
lentgh:映射的长度
1 /* fileMapTest.c*/ 2 /* 使用mmap对文件进行操作*/ 3 4 #include <stdio.h> 5 6 #include <sys/types.h> 7 #include <sys/stat.h>/* stat*/ 8 #include <fcntl.h> 9 #include <sys/mman.h>/* mmap*/ 10 #include <string.h> 11 //#include <unistd.h> 12 13 #define FILELENGTH 80 14 15 int main(void){ 16 int fd = -1; 17 char buf[] = "I love Smirk forever,I think of you every time"; 18 char *ptr = NULL; 19 20 fd = open("mmap.txt", O_RDWR/*读写*/|O_CREAT/*创建*/|O_TRUNC/*清空*/, S_IRWXU); 21 if(fd == -1){ 22 return -1; 23 } 24 25 lseek(3, (FILELENGTH - 1), SEEK_SET); 26 27 write(fd, "a", 1); 28 29 ptr = (char*)mmap(NULL, FILELENGTH, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 30 31 if(ptr == (char*)-1){ 32 printf("mmap failure\n"); 33 close(fd); 34 return -1; 35 } 36 37 memcpy((ptr + 16), buf, strlen(buf)); 38 39 munmap(ptr, FILELENGTH); 40 41 close(fd); 42 return 0; 43 }
8、fcntl() 文件属性函数
#include <sys/unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, flock *lock);
返回值:操作成功返回依赖于cmd,错误返回-1
fd:文件描述符
cmd:发送的命令
F_DUPFD:复制为文件描述符
F_GETFD、F-SETFD:获取/设置文件描述符
F_GETFL、F_SETFL:获取/设置问家状态
F_GETOWN、F_SETOWN、F_GETSIG、F_SETSIG:获取/设置信号发送对象
F_GETLK、F_SETLK、F_SETLKW:获取/设置记录锁
F_GETLEASE、F_SETLEASE:获取/设置文件租约