unix下的低级文件操作

一、文件的打开及创建
函数open打开或创建文件,返回文件描述符。
#include<fcntl.h>
int open(const char *filename, int oflag,.../*[model_t mode]*/);
参数说明:
filename 打开或创建文件的路径名
oflag 整形oflag指定了打开文件的方式, 定义如下

标志含义
O_RDONLY以只读的方式打开文件
O_WRONLY以只写的方式打开文件
O_RDWR以读写的方式打开文件
O_APPEND以追加的方式打开文件
O_CREAT创建一个文件
O_EXEC如果使用了O_CREAT而且文件已经存在,就会发生一个错误
O_NOBLOCK以非阻塞的方式打开一个文件
O_TRUNC如果文件已经存在,则删除文件的内容

O_RDONLY、O_WRONLY、O_RDWR三个标志只能使用任意的一个。
如果使用了O_CREATE标志,则使用的函数是int open(const char *pathname,int flags,mode_t mode); 这个时候我们还要指定mode标志,用来表示文件的访问权限。mode可以是以下情况的组合:

标志含义
S_IRUSR用户可以读
S_IWUSR用户可以写
S_IXUSR用户可以执行
S_IRWXU用户可以读、写、执行
S_IRGRP组可以读
S_IWGRP组可以写
S_IXGRP组可以执行
S_IRWXG组可以读写执行
S_IROTH其他人可以读
S_IWOTH其他人可以写
S_IXOTH其他人可以执行
S_IRWXO其他人可以读、写、执行
S_ISUID设置用户执行ID
S_ISGID设置组的执行ID

除了可以通过上述宏进行“或”逻辑产生标志以外,我们也可以自己用数字来表示,Linux总共用5个数字来表示文件的各种权限:第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位;第四位表示组的权限;最后一位表示其他人的权限。每个数字可以取1(执行权限)、2(写权限)、4(读 权限)、0(无)或者是这些值的和。

二、文件的关闭与删除
函数为close关闭一个打开的文件,函数unlink删除文件
#include<unistd.h>
int close(int filedes);
int unlink(char *pathname);
close关闭文件描述符filedes,成功时返回0,失败返回-1;
unlink删除文件,当且仅当文件的链接数为0时,同时没有被别的进程打开,文件占用的空间才被释放。函数成功时返回0,否则返回-1.


三、文件读写
#include<unistd.h>
size_t read(int fd, void *buf, size_t nbytes);
size_t write(int fd, const void *buf, size_t nbytes);
其中参数buf为指向缓冲区的指针,nbytes为缓冲区的大小(以字节为单位)。函数read()实现从文件描述符fd所指定的文件中读取 nbytes个字节到buf所指向的缓冲区中,返回值为实际读取的字节数。函数write实现将把nbyte个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数。


四、文件的定位
#include<unistd.h>
int lseek(int fd, offset_t offset, int whence);
lseek将文件读写指针相对whence移动offset个字节。操作成功时,返回文件指针相对于文件头的位置。参数whence可使用下述值:

SEEK_SET相对文件开头
SEEK_CUR相对文件读写指针的当前位置
SEEK_END相对文件末尾

offset可取负值,例如下述调用可将文件指针相对当前位置向前移动5个字节:
lseek(fd, -5, SEEK_CUR);
由于lseek函数的返回值为文件指针相对于文件头的位置,因此下列调用的返回值就是文件的长度:
lseek(fd, 0, SEEK_END);

五、文件的缓冲
#include<unistd.h>
int fsync(int fd);
系统调用fsync将所有已写入文件描述符fd的数据真正的写到磁盘或其它设备中,类似于标准文件库编程中的fflush,当系统调用成功时人才返回0,否则返回-1.

六、复制文件描述符
#include<unistd.h>
int dup(int fd);
int dup2(int fdsrc, int fddes);
dup复制文件描述符fd到当前未使用的最小可用文件描述中。
dup2复制文件描述fdsrc到fddes中。如果fddes已经打开,则关闭之,如果fddes与fdsrc值相等,则直接返回。这两个函数成功时都返回新的文件描述时,否则返回-1。
 
七、文件控制
1.fcntl
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, int arg);
int fcntl(int fd, int cmd, struct flock *arg);
参数说明:
fd 文件描述词。
cmd 操作命令。
arg 供命令使用的参数。
lock 同上。
fcntl对文件描述符执行各种控制命令,参数cmd确定了具体执行的命令和是否需要参数arg,cmd可选项如下:

F_DUPFD复制文件描述词
F_SETFD设置文件描述词标志
F_GETFD读取文件状态标志
F_SETFL设置文件状态标志
F_GETFL读取文件状态标志
F_GETOWN获取当前在文件描述词 fd上接收到SIGIO 或 SIGURG事件信号的进程或进程组标识
F_SETOWN设置将要在文件描述词fd上接收SIGIO 或 SIGURG事件信号的进程或进程组标识
F_GETLK用于锁处理
F_SETLK用于锁处理
F_SETLKW用于锁处理


fcbtl专用于锁时,其原形为 int fcntl(int fd, int cmd, struct flock *arg),结构struct flock用于描述锁的信息,定义如下
struct flock{
short l_type; //锁类型,F_RDLCK(申请)读锁,F_WRLCK(申请)写锁,F_UNLCK解锁
short l_whence; //锁区域开始地址的相对位置,取值为SEEK_SET、SEEK_CUR 、SEEK_END之一,与lseek中的whence类似;
long l_start; //锁区域开始地址偏移量。
long l_len; //锁区域的长度,0表示至文件尾。
short l_pid; //拥有所的进程ID号;
}

当fcntl用于锁时cmd的三种取值:
F_GETLCK
F_SETLCK
F_SETLKW
2.文件锁操作
在锁机制的使用中,最常见的有锁的申请、释放的测试等。

a.测试锁
/* 查看文件从start开始len字节内的锁情况 */
void SeeLock(int fd, int start, int len)
{
struct flock arg;
arg.l_type=F_WRLCK;
arg.l_whence = SEEK_SET;
arg.l_start = start;
arg.l_len = len;
if (fcntl(fd, F_GETLK, &arg) == -1) fprintf(stderr, "See Lock failed./n");
else if (arg.l_type == F_UNLCK) fprintf(stderr, "No Lock From %d To %d/n", start, len);
else if (arg.l_type == F_WRLCK) fprintf(stderr, "Write Lock From %d To %d, id=%d/n", start, len, arg.l_pid);
else if (arg.l_type == F_RDLCK) fprintf(stderr, "Read Lock From %d To %d, id=%d/n", start, len, arg.l_pid);
}

b.申请读锁
/* 在文件从start开始len字节内的申请读锁,阻塞模式 */
void GetReadLock(int fd, int start, int len)
{
struct flock arg;
arg.l_type=F_RDLCK;
arg.l_whence = SEEK_SET;
arg.l_start = start;
arg.l_len = len;
if (fcntl(fd, F_SETLKW, &arg) == -1) fprintf(stderr, "[%d] Set Read Lock failed./n", getpid());
else fprintf(stderr, "[%d] Set Read Lock From %d To %d/n", getpid(), start, len);
}

c.申请写锁
/* 在文件从start开始len字节内的申请写锁,阻塞模式 */
void GetWriteLock(int fd, int start, int len)
{
struct flock arg;
arg.l_type=F_WRLCK;
arg.l_whence = SEEK_SET;
arg.l_start = start;
arg.l_len = len;
if (fcntl(fd, F_SETLKW, &arg) == -1) fprintf(stderr, "[%d] Set Write Lock failed./n", getpid());
else fprintf(stderr, "[%d] Set Write Lock From %d To %d/n", getpid(), start, len);
}

d.释放锁
/* 释放文件从start开始len字节内的锁 */
void ReleaseLock(int fd, int start, int len)
{
struct flock arg;
arg.l_type=F_UNLCK;
arg.l_whence = SEEK_SET;
arg.l_start = start;
arg.l_len = len;
if (fcntl(fd, F_SETLKW, &arg) == -1) fprintf(stderr, "[%d] UnLock failed./n", getpid());
else fprintf(stderr, "[%d] UnLock From %d To %d/n", getpid(), start, len);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值