本文共 6990 字,大约阅读时间需要 23 分钟。
#include//头文件 #include #include 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); //文件名 权限 creat 函数等价于open(pathname,O_CREAT|O_TRUNC|O_WRONLY,mode);
open()函数出错时返回-1,相关参数如下:
flags 和 mode 都是一组掩码的合成值,flags 表示打开或创建的方式,mode 表示文件的访问权限。 mode参数只有在建立新文件时才会生效(flags中包含O_CREAT),表示新建文件的权限,但最终所建文件的权限会受到umask值所影响,因此该文件权限应该为(mode-umaks)。 flags 的可选项有O_RDONLY 以只读的方式打开 O_WRONLY 以只写的方式打开 O_RDWR 以读写的方式打开 O_CREAT 如果文件不存在,则创建文件 O_EXCL 仅与 O_CREAT 连用,如果文件已存在,则强制 open 失败 O_TRUNC 如果文件存在,将文件的长度截至 0 O_APPEND 已追加的方式打开文件, 每次调用 write 时,文件指针自动先移到文件尾,用于多进程写一个文件的情况。 O_NONBLOCK 非阻塞方式打开,无论有无数据读取或等待,都会立即返回进程之中。 O_NODELAY 非阻塞方式打开 O_SYNC 同步打开文件,只有在数据被真正写入物理设备设备后才返回
mode的可选项有:
mode 的可选项有: S_IRWXU 00700 权限,代表该文件所有者具有可读、可写及可执行的权限。 S_IRUSR 00400 权限,代表该文件所有者具有可读取的权限。 S_IWUSR 00200 权限,代表该文件所有者具有可写入的权限。 S_IXUSR 00100 权限,代表该文件所有者具有可执行的权限。 S_IRWXG 00070 权限,代表该文件用户组具有可读、可写及可执行的权限。 S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。 S_IWGRP 00020 权限,代表该文件用户组具有可写入的权限。 S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。 S_IRWXO 00007 权限,代表其他用户具有可读、可写及可执行的权限。 S_IROTH 00004 权限,代表其他用户具有可读的权限 S_IWOTH 00002 权限,代表其他用户具有可写入的权限。 S_IXOTH 00001 权限,代表其他用户具有可执行的权限。
close 用于文件的关闭:
int close(int fd); //fd 表示文件描述符,是先前由 open 或 creat 创建文件时的返回值。
文件使用完毕后,应该调用 close 关闭它,一旦调用 close,则该进程对文件所加的锁全都被释放,并且使文件的打开引用计数减 1,只有文件的打开引用计数变为 0 以后,文件才会被真正的关闭。
#includeint main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); int fd; fd = open(argv[1],O_RDWR); ERROR_CHECK(fd, -1, "open"); printf("fd=%d\n",fd); close(fd); return 0;}
#includeint main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); int fd; fd = open(argv[1],O_RDWR|O_CREAT,0666); ERROR_CHECK(fd, -1, "open"); printf("fd=%d\n",fd); return 0;}
#includessize_t read(int fd, void *buf, size_t count); //文件描述符 缓冲区 长度 ssize_t write(int fd, const void *buf, size_t count);
fd:文件描述符 buf:写入的字符串,传入指向字符串的指针 count:写入的字节数
对于read函数同理,buf为读出的缓冲区,count为读出的字节数 read 和 write 函数,出错返回-1,读取完了之后,返回 0, 其他情况返回读写的个数read.c
#includeint main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); int fd; fd = open(argv[1],O_RDWR); ERROR_CHECK(fd, -1, "open"); printf("fd=%d\n",fd); char buf[128]={ 0}; int ret = read(fd,buf,sizeof(buf)); printf("buf=%s,ret=%d\n",buf,ret); close(fd); return 0;}
write.c
#includeint main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); int fd; fd = open(argv[1],O_RDWR); ERROR_CHECK(fd, -1, "open"); printf("fd=%d\n",fd); int ret = write(fd,&fd,sizeof(int)); printf("write count = %d\n",ret); close(fd); return 0;}
案例:将 aaa.txt 中的内容复制到 bbb.txt 中,其中 bbb.txt 起初不存在
#include#include //包含 exit #include #include #include #include //用 perror 输出错误 #include #define FILENAME1 "./aaa.txt" //用宏定义文件的路径#define FILENAME2 "./bbb.txt"int main() { char buf[512] = { 0}; int fo1 = open(FILENAME1, O_RDONLY); //fo1,fo2 都是文件描述词 int fo2 = creat(FILENAME2, 0755); //创建文件 //int fo2 = open(FILENAME2, O_WRONLY | O_CREAT); if( (-1 == fo1) || (-1 == fo2) ) { perror("open failed!\n"); //用于输出错误信息.类似于:fputs(”open failed\n”,stderr); exit(-1); } int fr = 0; while( (fr = read(fo1, buf, sizeof(buf))) > 0 ) //如果 read 读取成功,返回的是长度,否则,返回-1 { int fw = write(fo2, buf, fr); if( -1 == fw ) { perror("write failed!"); exit(-1); } } close(fo1); close(fo2); }
#includeint ftruncate(int fd, off_t length);
函数 ftruncate 会将参数 fd 指定的文件大小改为参数 length 指定的大小。参数 fd 为已打开的文
件描述词,而且必须是以写入模式打开的文件。如果原来的文件大小比参数 length 大,则超过的 部分会被删去。 返回值 执行成功则返回 0,失败返回-1。#include#include int main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); int fd; fd = open(argv[1],O_RDWR); ERROR_CHECK(fd, -1, "open"); printf("fd=%d\n",fd); int ret = ftruncate(fd,50); ERROR_CHECK(ret,-1,"ftruncate"); close(fd); return 0;}
int main() { int fd = open("a.txt", O_WRONLY); ftruncate(fd, 1000); close(fd); return 0; }
#include#include off_t lseek(int fd, off_t offset, int whence);
函数 lseek 将文件指针设定到相对于 whence,偏移值为 offset 的位置
whence 可以是下面三个常量的一个SEEK_SET 从文件头开始计算 SEEK_CUR 从当前指针开始计算 SEEK_END 从文件尾开始计算
利用该函数可以实现文件空洞(对一个新建的空文件,可以定位到偏移文件开头 1024 个字节的地
方,在写入一个字符,则相当于给该文件分配了 1025 个字节的空间,形成文件空洞)通常用于多 进程间通信的时候的共享内存。int main() { int fd = open("c.txt", O_WRONLY | O_CREAT); lseek(fd, 1024, SEEK_SET); write(fd, "a", 1); close(fd); return 0; }
可以通过 fstat 和 stat 函数获取文件信息,调用完毕后,文件信息被填充到结构体 struct stat变量中,函数原型为:
#include#include #include int stat(const char *file_name, struct stat *buf); //文件名 stat 结构体指针 int fstat(int fd, struct stat *buf); //文件描述符 stat 结构体指针
结构体 stat 的定义为:
struct stat { dev_t st_dev; /*如果是设备,返回设备表述符,否则为 0*/ ino_t st_ino; /* i 节点号 */ mode_t st_mode; /* 文件类型 */ 无符号短整型 nlink_t st_nlink; /* 链接数 */ uid_t st_uid; /* 属主 ID */ gid_t st_gid; /* 组 ID */ dev_t st_rdev; /* 设备类型*/ off_t st_size; /* 文件大小,字节表示 */ blksize_t st_blksize; /* 块大小*/ blkcnt_t st_blocks; /* 块数 */ time_t st_atime; /* 最后访问时间*/ time_t st_mtime; /* 最后修改时间*/ time_t st_ctime; /* 最后权限修改时间 */ };
对于结构体的成员 st_mode,有一组宏可以进行文件类型的判断:
S_ISLNK(mode) 判断是否是符号链接 S_ISREG(mode) 判断是否是普通文件 S_ISDIR(mode) 判断是否是目录 S_ISCHR(mode) 判断是否是字符型设备 S_ISBLK(mode) 判断是否是块设备 S_ISFIFO(mode) 判断是否是命名管道 S_ISSOCK(mode) 判断是否是套接字
#include#include int main() { struct stat buf; stat (“/etc/passwd”,&buf); printf(“/etc/passwd file size = %d \n”,buf.st_size);//st_size 可以得到文件大小 return 0;} //如果用 fstat 函数实现,如下: int fd = open (“/etc/passwd”,O_RDONLY); //先获得文件描述符fstat(fd, &buf);
#include#include #include #include #include #include #include #include int main() { int fd = open("/home/wangxiao/0926/a.txt", O_RDONLY); if(fd == -1) { perror("open error"); exit(-1); } struct stat buf; int iRet = fstat(fd, &buf); if(iRet == -1) { perror("fstat error"); exit(-1); } if(S_ISREG(buf.st_mode)) { printf("regular file!\n"); } if(S_ISDIR(buf.st_mode)) { printf("directory!\n"); } if(S_ISLNK(buf.st_mode)) { printf("link file!\n"); } printf("the size of file is : %d\n", buf.st_size); time_t tt = buf.st_atime; struct tm *pT = gmtime(&tt); printf("%4d-%02d-%02d %02d:%02d:%02d\n", (1900+pT->tm_year), (1+pT->tm_mon), pT->tm_mday, (8+pT->tm_hour), pT->tm_min, pT->tm_sec); printf("the last access time is : %d\n", buf.st_atime); close(fd); return 0; }
转载地址:http://faxmb.baihongyu.com/