linux系统应用学习(五)--- 基于非缓冲区的文件操作

一、系统调用

系统调用 是内核提供给应用层的一系列接口函数,应用层调用接口函数让内核完成一定的任务。

二、常用文件操作函数

标C:fopen  fread  fwrite  fgets  fseek  fclose(基于有缓冲区的)

UC: open  read  write  lseek  close  (非缓冲区)

文件操作:

1.打开文件    open

       #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);

pathname :文件路径

flags :标志位

O_RDONLY:以只读方式打开文件

O_WRONLY:以只写方式打开文件

O_RDWR:以读写方式打开文件

O_CREAT:如果改文件不存在,就创建一个新的文件,并用第三个参数为其设置权限

O_EXCL:如果使用O_CREAT时文件存在,则返回错误消息。这一参数可测试文件是否存在。此时open是原子操作,防止多个进程同时创建同一个文件

O_NOCTTY:使用本参数时,若文件为终端,那么该终端不会成为调用open()的那个进程的控制终端
O_TRUNC:若文件已经存在,那么会删除文件中的全部原有数据,并且设置文件大小为0
O_APPEND:以添加方式打开文件,在打开文件的同时,文件指针指向文件的末尾,即将写入的数据添加到文件的末尾

O_NONBLOCK: 如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式。

O_SYNC:使每次write都等到物理I/O操作完成。
O_RSYNC:read 等待所有写入同一区域的写操作完成后再进行
在open()函数中,falgs参数可以通过“|”组合构成,但前3个标准常量(O_RDONLY,O_WRONLY,和O_RDWR)不能互相组合。

mode:被打开文件的存取权限,可以用两种方法表示,可以用一组宏定义:S_I(R/W/X)(USR/GRP/OTH),其中R/W/X表示读写执行权限,

USR/GRP/OTH分别表示文件的所有者/文件所属组/其他用户,如S_IRUUR|S_IWUUR|S_IXUUR,(-rex------),也可用八进制800表示同样的权限,如:

mode:文件权限  0644(可读可写)

0表示没有权限,1表示可执行权限,2表示可写权限,4表示可读权限,然后将其相加。

返回值:

成功:返回文件描述符(一个整数)

失败:返回-1

 

2.读写操作 read write

read:

  #include <unistd.h>

                ssize_t read(int fd, void *buf, size_t count);

fd:文件描述符

buf:存放数据缓冲区

count:要读的字节个数,以字节为单位

返回值:成功返回读的字节个数,到文件末尾返回0.出错返回-1。

write:

 #include <unistd.h>

 ssize_t write(int fd, const void *buf, size_t count);

基本跟read函数一样。

返回值:成功返回真正写到文件当中字节的个数,出错返回-1。

3.关闭文件 close

 #include <unistd.h>

  int close(int fd);

注意:操作文件时尽量不要边读边写,最好先写,写完关闭,再以读的方式打开。

三、文件位置指针

记录了打开的文件读写位置

操作文件位置指针 lseek

#include <sys/types.h>

#include <unistd.h>

off_t  lseek(int fildes, off_t offset, int whence);

fildes:文件描述符

offset:移动的字节个数  正数向右  负数向左移动

whence:相对位置

SEEK_SET   0  //文件开头

SEEK_CUR   1  //从当前位置

SEEK_END   2  //从文件末尾

返回值:返回文件位置指针所在的文件位置(即第几个字节),失败返回-1。

例:lseek(fd,0,SEEK_END);  //求文件大小

四、文件描述符

文件描述符表,(其实就是个指针数组),每运行一个程序,系统会给程序建立一个文件描述符表,它记录了程序打开的所有文件描述符。每打开一个文件,会把文件结构体的地址写到表里面,然后返回文件描述符(文件描述符可以理解为序号、数组下标、一个唯一对应的整型数),每个程序最多打开1024个文件。

1.每个程序运行时都会默认打开三个文件描述符,即标准输入,标准输出,标准错误。

标准C   stdin                       stdout                           stderr

UC  STDIN_FILENO  STDOUT_FILENO  STDERR_FILENO

2.文件描述符的复制 dup

 #include <unistd.h>

  int dup(int oldfd); 随机返回新的描述符

  int dup2(int oldfd, int newfd); 返回指定新文件描述符

参数:

oldfd : 源文件描述符

newfd : 新文件描述符

返回值:成功返回新的文件描述符,失败返回-1;

dup和普通的赋值的区别:当你fd2=fd1;都指向一个文件,然后当你close(fd1),fd2也同时失效。相当于整个文件与文件描述符数组的关系切断了。而你用dup的时候,即使关掉一个close(fd1),fd2依然可以用。

3.文件锁

在多进程当中,多个进程对同一个文件读写操作,可能造成数据的冲突。所以引入了文件锁,对正在操作的文件进行保护。

文件锁分为读锁和写锁

当一个进程在操作文件之前对文件加读锁,其他进程再加读锁可以加成功(即可以同时读)。但是其他进程加写锁是不成功的。

当一个进程对文件加了写锁,其他进程加读锁和写锁都不成功。

文件锁是影响了其他进程是否能够加锁成功,但不影响其他进程对文件的读写操作。(也就是说需要大家都遵守规定。如果某进程不遵守,你也没办法。所以某种意义上文件锁对于不遵守规定的人并没有什么卵用)

fcntl ( )+锁结构体

 #include <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, struct flock *lock);

参数:

fd:文件描述符

cmd :  F_DUPFD  //复制文件描述符

F_GETFD //获取文件描述符标志位

F_SETFD   //设置文件描述符标志位

F_GETFL   //获取文件状态标志位

F_SETFL    //设置文件状态标志位

F_GETLK   //获取锁

F_SETLK   //设置锁 非阻塞

F_SETLKW  //设置锁   阻塞(即等待)

lock:

struct flock

{

   short l_type;    /*(锁类型) Type of lock: F_RDLCK,

              F_WRLCK, F_UNLCK(解锁) */

   short l_whence;  /* 加锁的相对位置:

                           SEEK_SET, SEEK_CUR, SEEK_END */

   off_t l_start;   /* 距相对位置差多少,即加锁的实际开                            始位置*/

   off_t l_len;     /* 加锁区域的长度 */若上个参数和这                                   个参数均为0,则表示给整个文件加锁。

   pid_t l_pid;     /*一般赋-1 PID of process blocking our                                              lock  (F_GETLK only) */

           ...

  };

返回值:成功返回0;失败返回-1。

五、获取文件状态

fstat  stat  lstat

#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 lstat(const char *path, struct stat *buf);

参数:

path:文件路径

filedes:文件描述符

返回值成功是0,失败-1.

 struct stat {

 dev_t     st_dev;     /* 设备号 */

 ino_t     st_ino;     /* 设备节点号 */

 mode_t    st_mode;    /* 权限*/

 nlink_t   st_nlink;   /* 硬链接个数 */

 uid_t     st_uid;     /* user ID of owner */

 gid_t     st_gid;     /* group ID of owner */

 dev_t     st_rdev;    /* device ID (if special file) */

 off_t     st_size;    /* 文件大小 in bytes */

 blksize_t st_blksize; /* blocksize for filesystem I/O */

 blkcnt_t  st_blocks;  /* number of blocks allocated */

 time_t    st_atime;   /*最近访问时间*/

 time_t    st_mtime;   /*最近更改时间*/

 time_t    st_ctime;   /* 最近文件状态改变时间*/

  };

通过st_mode判断文件类型

 S_ISREG(m)  普通文件?

       S_ISDIR(m)  目录文件?

 S_ISCHR(m)  字符文件?

 S_ISBLK(m)  块设备?

 S_ISFIFO(m) 管道文件?

 S_ISLNK(m)  是否是链接文件?(Not in POSIX.1-1996.)

 S_ISSOCK(m)  是否是套接字? (Not in POSIX.1-1996.)

 

S_IFMT     0170000   bitmask for the file type bitfields

S_IFSOCK   0140000   socket

S_IFLNK    0120000   symbolic link

S_IFREG    0100000   regular file

S_IFBLK    0060000   block device

S_IFDIR    0040000   directory

S_IFCHR    0020000   character device

       S_IFIFO    0010000   FIFO

       S_ISUID    0004000   set UID bit

       S_ISGID    0002000   set-group-ID bit (see below)

       S_ISVTX    0001000   sticky bit (see below)

       S_IRWXU    00700     mask for file ownepermissions

       S_IRUSR    00400     owner has read permission

       S_IWUSR    00200     owner has write permission

              S_IXUSR    00100     owner has execute permission

       S_IRWXG    00070     mask for group permissions

       S_IRGRP    00040     group has read permission

       S_IWGRP    00020     group has write permission

       S_IXGRP    00010     group has execute permission

       S_IRWXO    00007     mask for permissions for                                                                                 others (not in group)

       S_IROTH    00004     others have read permission

       S_IWOTH    00002     others have write permission

       S_IXOTH    00001     others have executepermission

猜你喜欢

转载自blog.csdn.net/qq_38639426/article/details/89045822