文件看过去好久了,还是做个总结吧,顺便温习一下。
我们需要知道:shell命令是操作系统提供给普通用户使用的接口,而系统调用是操作系统提供给程序员使用的接口。
首先,对于文件,我们要明白,
Linux中一切都是文件!这就意味着程序可以像处理普通文件一样对待磁盘文件。文件主要包含两个方面的内容:一个是文件本身所包含的数据,一个是文件的属性(包括文件访问权限,所有者,文件大小,创建日期等等)
目录也是一种文件,它的内容是该目录的目录项,当创建一个新目录的时候,系统将自动创建两个目录想:.和..在shell下输入ls -a 可以将其显示在终端,前者代表当前目录,后者代表当前目录的父目录。
一:Linux的文件系统
文件最后都是存储在物理磁盘上的,操作系统通过文件系统可以方便的对磁盘上的文件进行管理。
对物理磁盘的访问都是通过设备驱动程序来进行的。对设备驱动的访问有两种:1)通过设备驱动本身的接口。2)通过虚拟文件系统VFS提供给上层应用程序的接口。(VFS是虚拟的不存在的,它只存在于内存并不存在于磁盘。VFS将各种不同的文件系统整合在一起,提供同一的应用程序编程接口API给上层应用程序使用。)
文件系统是由一系列块构成的,文件系统一旦安装,快的大小就固定了。(一个块的大小是一个扇区的大小,通常为512字节)
二:文件的分类(这里只列出最常见的集中)
(1)普通文件:最常见的文件类型,包含何种类型的数据对内核而言并无区别,对普通文件内容的解释由处理该文件的应用程序完成。
(2)目录文件:目录文件就是目录,设有自己的访问权限,目录的内容就是该目录下的文件和子目录的信息,对伊个目录文件具有读许可权的任意进程都可以读取该目录的内容,但 只有内核可以写目录文件。
(3)FIFO:这种类型的文件是进程见通信的命名管道
(4)套接字:主要用于网络通信
(5)符号连接:指向另一个文件,是另一个文件的引用
三:文件的访问权限控制
ls -l
查看某一文件的属性
访问权限:第一组表示文件所有者对文件的操作权限,第二组表示文件所有者同组的用户对文件的操作,第三组是其他用户对文件的访问权限
r:可读 w:可写 x:可执行
r=4,w=2,x=1
shell下通过chmod命令可以修改文件的操作权限
eg:chmod 777 test.c表示将文件test.c的操作权限修改为可读可写可执行。
也可以通过chmod/fchmod函数对其操作权限进行修改
其头文件是:
- #include<sys/types.h>
- #include<sys/stat.h>
- int chmod(const char *path,mode_t mode);
- int fchmod(int fildes,mode_t mode);
四:文件的输入输出:
对于内核而言,所有打开的文件都由文件描述副表示。在读写之前,文件一定必须调用open/create函数打开。成功执行这两个函数都会返回一个文件描述符,在进行读写操作的时候就要将其作为参数传递给read/write。(每个程序最多能打开256个文件)
1:文件的创建,打开,关闭
(1):打开
- #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);
flags:
O_RDONLY(以只读的方式打开)
O_WRONLY(以只写的方式打开)
O_RDWR(以可读可写的方式打开)
O_CREAT(若文件不再就自动建立该文件,只有在此时才用的上第三个参数)
O_EXCL(和CREAT连用,文件若不在则创建,若存在则返回错误)
O_TRUNC:若文件存在并且以可写的方式打开,此标志会将文件长度清零。
O_NONBLOCK:以非阻塞的方式打开,对于open及随后的对该文件的操作都会立即返回
(2)创建
int creat(const char *pathname,mode_t mode);
如果pathname所指向的文件不存在则创建,存在则被新文件覆盖。
creat函数无法创建设备文件,设备文件的创建要使用mknod函数。//有名管道的创建
(3)关闭
#include
int close(int fd);
close调用成功也不保证数据能全部写回到硬盘。
(4)读
#include
ssize_t read(int fd,void *buf,size_t count);
从文件描述符fd所指向的文件中读取count个字节的数据到buff锁指向的缓存中。
如果count设置为0,则表示文件已经到达文件尾,无可再读取的数据,此外文件读写指针会随着读取到的字节移动,如果read读取顺利则返回实际读到的字节书,最好能返回值与参数作比较,若返回的字节数目比要求读取的字节数少,则游客能读到文件尾部或者被终端了读取过程。
(5)写
#include
ssize_t write(int fd,const void *buf,size_t count);
将buf锁指向的缓冲区中count个字节的数据写入到文件描述副fd锁指向的文件中
(6)文件读写指针的移动
#include
#include
off_t lseek(int fildes,off_t offset,int whence)
fildes是指打开文件的文件描述符号
offset为根据参数whence来移动读写位置的位移数
whence的取值:
SEEK_SET:从文件开始处计算,文件指针到文件开始处距离:offset
SEEK_CUR:从此当前位置计算,文件指针到当前位置加上offset
SEEK_END:从文件结尾出开始计算,文件指针到文件尾加上offset
lseek允许文件指针的值设置到文件结束符号EOF之后,但不会改变文件大小,如果用write对EOF位置写入数据,之前的EOF处与后面写入数据之间将会产生一个间隔。
用法:
(1)将文件读写指针移动到文件开头
lseek(int fildes,0,SEEK_SET);
(2)将文件读写指针移动到文件末尾
lseek(int fildes,0,SEEK_END);
(3)将文件读写指针停留在当前位置
lseek(int fildes,0,SEEK_CUR);
2:dup,dup2,fcntl,ioctl的系统调用
(1)dup,dup2
#include
int dup(int oldfd);
int dup2(int newfd);//dup用来复制参数oldfd所指向的文件描述符,复制成功,返回最小的尚未被使用的文件描述符,若有错误返回-1。返回的新文件描述副和旧文件描述符指向同一个文件。例如:当利用lseek()对某个文件描述副操作的时候,另外一个文件描述副的读写位置也会随之改变。
(2)fcntl函数
#include
#include
int fcntl(int fd,int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock *lock);
F_DUPFD:此时,可以复制fd指向的文件描述符
F_GETFD:fcntl用来获取文件描述副的close-on-exec标志,调用成功返回标志符号,若此标志副最后一位是0,则该标志没有设置,意味着在执行exec相关函数后文件描述符依旧保持打开。
F_SETFD:此时,fcntl用来设置文件描述副的close-on-exec标志为第三个参数arg的最后以为,成功返回0
F_GETFL:此时,fcntl用来获得文件打开的方式,成功返回标志值,失败返回-1
F_SETFL:fcntl用来设置文件打开的方式为第三个参数arg制定的方式。//O_ASYNC,O_NONBLOCK,O_APPEND
接下来的fcntl函数3种功能都与记录锁有关系:
文件记录锁:当有多个进程同时对某个文件进行操作的时候,就可能发生数据的不同步,从而引起错误。该文件最后状态取决于该文件的最后一个程序,但是对于应用程序,有时候进程需要确保它正在单独写一个文件,提出了记录锁机制
- struct flock
- {
- short_l_type;//leixing
- short_l_whence;//pianyiliang
- off_t_l_start;//starting offset for lock
- off_t_l_len;//number of bytes to lock
- pid_t_l_pid;//suode jincheng ID
- };
l_type用来设置共享锁/互斥锁。多个进程在一个给定的字节上可以有一把共享的读锁,但是在一个给定字节上的写锁却只有一个进程单独使用//读写锁?
(未完成)
阅读(1612) | 评论(0) | 转发(0) |