linux下文件的操作
第一次写博客,感觉很奇妙,写什么?确实很纠结,想想还是总结一下这周学到的自我觉得容易忘记的东西吧,方便以后复习.
主要有以下两点
- 文件的创建、打开与关闭
- 获取文件属性
(1) 文件的创建与打开
这里主要用到
open
和creat
函数以及close
函数
open
:系统调用用来打开或创建一个文件
creat
:系统调用用来创建一个文件
close
:系统调用用来关闭一个已经打开的文件
以下是它们的函数原型和对应的头文件
一. 对于open
函数,它的第一个参数pathname
是要打开和创建的含路径的文件名
。
第二个参数flags
是要打开文件的方式,这里flags
需要着重注意,flags分为两类:主类,副类
主类:
1. O_RDONLY:以只读方式打开文件
2. O_WRONLY :以只写方式打开文件
3. O_RDWR :以可读可写方式打开文件
这三种打开方式互斥的,切不可同时使用。
副类:
1. O_CREAT :若文件不存在则自动创建该文件,只有此时,才使用第三个参数mode,来说明新文件的存取权限。
2. O_EXCL :如果O_CREAT也被设置,则此指令会去检查文件是否存在,若文件存在则降到只打开文件出错,否则创建该文件
3. O_TRUNC :如果文件已经存在则且以可写的方式打开时,删除文件中原有数据,但文件属性不变。
4. O_APPEND :所写入的数据会以追加的方式加入到文件后面。
5. O_SYNC:以同步的方式打开文件,任何对文件的修改都会阻塞知道物理磁盘上的数据同步以后才返回。
注:还有几个副类,这里列出的几个我觉得比较常用的。
主副可以配合使用,例如:O_RDWR|O_CREAT|O_TRUNC
调用
open
函数成功后返回一个文件描述符
,若有错误发生则返回-1,并把错误代码赋给errno
二.creat
函数中第一个参数pathname 是要打开和创建的文件名,如果pathname指向的文件不存在,则创建一个新文件,否则原文件将被新文件覆盖。第二个参数mode与open函数相同,这里它不同于open函数的主要是,creat只能以只写的方式打开创建的文件,且无法创建设备文件
。
函数原型:
int creat (const char *pathname,mode_t mode);
它就等价于:
open(pathname,O_CREAT | O_TRUNC | O_WRONLY,mode);
和open一样,creat也在调用成功后返回一个文件描述符,如果失败,则设置errno变量并返回-1.
三.close
函数就一个参数,即需要关闭的文件的文件描述符(由open或creat函数得到的)。
调用成功返回0,失败返回-1,并设置错误代码。
(2)获取文件属性
这里需要用到
stat/fstat/lstat
这三个函数,原型及其包含的头文件如下:
它们执行成功都返回0,有错误发生则返回-1,错误代码存入errno中.
三个函数的区别:
stat 用于获取由参数pathname指定的文件名的状态信息,保存在参数struct stat *statbuf中。
fstat与stat的区别是fstat是通过文件描述符来指定文件的。
fstat与stat的区别在于`对于符号链接文件,lstat返回的是符号链接文件本身的状态信息,而stat返回的的是符号链接指向的文件状态信息。
然后是struct stat *statbuf 结构体的定义如下:
struct stat
{
dev_t st_dev; /* ID of device containing file -文件所在设备的ID*/
ino_t st_ino; /* inode number -inode节点编号*/
mode_t st_mode; /* protection -文件的类型和存取权限*/
nlink_t st_nlink; /* number of hard links -连到该文件的硬链接数目,刚建立的文件值为1*/
uid_t st_uid; /* user ID of owner -文件所有者的用户id*/
gid_t st_gid; /* group ID of owner - 文件所有者的组id*/
dev_t st_rdev; /* device ID (if special file) -设备号,针对设备文件*/
off_t st_size; /* total size, in bytes -文件大小,字节为单位,对符号链接,该大小是其所指向的文件名的长度*/
blksize_t st_blksize; /* blocksize for filesystem I/O -文件系统的I/O缓冲区大小*/
blkcnt_t st_blocks; /* number of blocks allocated -文件所占块数*/
time_t st_atime; /* time of last access -文件最近一次被访问的时间*/
time_t st_mtime; /* time of last modification -文件最后一次被修改的时间,一般只能调用utime和write函数时才会改变*/
time_t st_ctime; /* time of last status change - 文件最近一次被更改的时间*/
};
st_mode定义了以下几种情况:
S_IFMT 0170000 文件类型的位遮罩
S_IFSOCK 0140000 scoket
S_IFLNK 0120000 符号连接
S_IFREG 0100000 一般文件
S_IFBLK 0060000 区块装置
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置
S_IFIFO 0010000 先进先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限
对于st_mode包含的文件类型,POSIX标准定义了检查这些类型的宏,如下:
S_ISLNK (st_mode) 判断是否为符号连接
S_ISREG (st_mode) 是否为一般文件
S_ISDIR (st_mode) 是否为目录
S_ISCHR (st_mode) 是否为字符装置文件
S_ISBLK (s3e) 是否为先进先出
S_ISFIFO(st_mode)判断是否为先进先出FIFO
S_ISSOCK (st_mode) 是否为socket
下面为代码示例:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<errno.h>
int main(int argc,char *argv[])
{
char buf_time[40];
struct stat buf;
//检查参数个数
if (argc != 2)
{
printf("Usage: my_stat <filename>\n");
exit (0);
}
//获取文件属性
if( stat(argv[1],&buf) == -1 )
{
perror("stat:");
exit(1);
}
printf("File type: ");
if(S_ISLNK(buf.st_mode))
{
printf("symbolic (soft) link\n");
}
else if(S_ISREG(buf.st_mode))
{
printf("regular file\n");
}
else if(S_ISDIR(buf.st_mode))
{
printf("directory\n");
}
else if(S_ISCHR(buf.st_mode))
{
printf("character device\n");
}
else if(S_ISBLK(buf.st_mode))
{
printf("block device\n");
}
else if(S_ISFIFO(buf.st_mode))
{
printf("FIFO or pipe\n");
}
else if(S_ISSOCK(buf.st_mode))
{
printf("socket\n");
}
//打印出文件属性
printf("device is: %d\n",(int)buf.st_dev);
printf("inode is: %ld\n", (long)buf.st_ino);
printf("mode is: %o\n", buf.st_mode);
printf("number of hard links is: %ld\n", (long)buf.st_nlink);
printf("user ID of owner is: %ld\n", (long)buf.st_uid);
printf("group ID of owner is: %ld\n",(long)buf.st_gid);
printf("device type (if inode device) is: %ld\n",(long) buf.st_rdev);
printf("total size, in bytes is: %lld\n", (long long)buf.st_size);
printf("blocksize for filesysem I/O is: %ld\n",(long) buf.st_blksize);
printf("number of blocks allocated is: %lld\n", (long long)buf.st_blocks);
printf("time of last access is: %s",ctime(&buf.st_atime));
printf("time of last modification is: %s",ctime(&buf.st_mtime));
printf("time of last chang is: %s", ctime(&buf.st_ctime));
return 0;
}
运行结果
:
好了,这篇先就总结这么多吧,以后再继续补充,第一次写,还是不能保证简洁,全面,精确,以后改进!