Unix编程文件操作

 

目录

 

1、文件有哪些操作?

2、文件表和文件描述符

3 函数详解

3.1 open()函数

3.2 read()

3.3 write()

3.4 close

3.5 lseek()

3.6 fcntl()

3.7 access()函数

 

4、目录的操作

 

5、目录操作的函数

5.1 mkdir()

5.2 rmdir()

5.3 chdir()

5.4 opendir()

5.5 readdir()

5.6 closedir()


1、文件有哪些操作?

1、打开文件,函数open()

2、读取文件,函数read()

3、写文件,函数write()

4、关闭文件,函数close()

5、控制文件,函数ioctl()

 

2、文件表和文件描述符

当系统打开一个文件时,会把文件的各种信息放入一段内存中,这段内存叫文件表,但文件表比较大,不利于传参等参数,因此文件表不对外提供,对外提供文件表的编号,这个文件表的编号叫文件描述符。文件描述符的本质就是一个非负整数,必须对应一张文件表才有效。每个进程都有自己的文件描述符的总表,记录了文件描述符和文件表的对应关系。

“0” “1” “2”已经被系统预先使用,代表标准输入、标准输出和标准错误。表述符从3开始,最大到OPEN_MAX(Linux一般是256个)。

文件描述可以循环利用。close()以后可以再次使用。

3 函数详解

3.1 open()函数

头文件:

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

int open(const char*filename,int flags,...)

参数filename 就是文件名(包括路径),参数flags是打开的标志,主要包括:

O_RDONLY (只读),O_WRONLY(只写) ,O_RDWR(读写):打开的权限,三个必选其一。

O_CREAT : 创建标识,文件存在就打开,不存在就新建。

O_TRUNC : 打开文件时,自动清空文件(open()时清空)。

O_EXCL : 文件不存在,新建,文件存在就返回-1代表出错。

    这两个一般结合O_CREAT使用。

O_APPEND : 采用追加的方式打开文件,一般用于写

参数 “...”代表0-n个任意类型的参数,open()函数的第三个参数只在新建文件时有用,传入文件在硬盘上的权限。成功返回文件描述符,失败返回-1.

注:文件在硬盘上的权限与程序无关,程序的权限是打开权限,打开权限应该是文件在硬盘上的权限的一部分。

返回,成功返回文件描述符,失败返回-1.

 

3.2 read()

头文件

#include<unistd.h>

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

功能:从指定文件读取数据

描述:

fd是文件描述符,buf是传出参数,count是你想要读的大小,一般就是buf指向的内容的大小,当然,也可以比其小。

返回,成功返回读到的字节数,失败返回-1

 

3.3 write()

头文件

#include<unistd.h>

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

功能:向指定文件写入数据

描述:

fd是文件描述符,buf是要写入的数据的指针,length是要写入数据的大小。

返回,写入成功返回写入数据的大小,失败返回-1

 

3.4 close

头文件

#include<unistd.h>

int close(int fd);

功能:关闭一个文件描述符

描述:

fd 是要关闭的文件描述符

返回,如果成功返回0,失败返回-1.

 

3.5 lseek()

头文件:

#include<sys/types.h>

#include<unistd.h>

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

功能:指定文件读写的位置

描述:

fd文件描述符,offset 是偏移量,whence是偏移的起始位置,有三个值:

SEEK_SET  --从文件头开始计算偏移

SEEK_CUR  --从当前位置计算偏移

SEEK_END  --从文件尾计算偏移

返回:移动以后的位置和文件头的距离,返回失败-1。

注:这个返回值可以用来获取文件的大小,标C中要用fseek()+ftell()获取文件的大小。使用vi时,大多数情况下wq会自动加一个vi的结束符,因此会多一个字节。一般都使用SEEK_SET,个别时候使用SEEK_END

 

3.6 fcntl()

头文件:

#include<unistd.h>

#include<fcntl.h>

int fcntl(int fd,int cmd,...);

功能:对文件加锁

描述:

参数fd就是文件描述符,cmd是命令,...代表0-n个任意类型的参数

返回和cmd的选择有关。

cmd主要包括:

    F_DUPFD - 复制文件描述符,需要传入第三个参数做新的描述符的值,如果这个值已经被使用,找大于该值的未使用的最小值。

    F_SETFL/F_GETFL -设置/获取文件描述符的状态,SETFL基本用不到,因为只能修改O_APPEND;F_GETFL不需要第三个参数,可以获取权限和O_APPEND,创建标识无法获取。

    F_SETLK/F_SETLKW  -设置文件锁

文件锁 允许多个文件同时读,但不允许同时写,有的读有的写也不行。因此文件锁分为读锁和写锁。读锁针对读操作,效果允许其他进程读文件,但是不允许写。写锁针对写操作,效果是不允许其他进程读和写。

文件锁的使用是一个函数+一个结构:

fcntl()函数 + struct flock(失败返回-1)

fcntl(int fd,F_SETLK/F_SETLKW,struct flock*)。

struct flock{

       short l_type;//锁的类型,包括读锁、写锁和释放锁

       short l_whence;//锁定起始点的参考位置

       off_t l_start; //锁定起始点的偏移量

       off_t l_len;   //锁定区域的大小,锁定的长度

    pid_t l_pid;   //锁定进程的pid,只有GETLK时用到,给-1即可

};

l_type锁的类型:F_RDLCK(读锁)/F_WRLCK(写锁)/F_UNLCK(解锁)

l_whence的值:SEEK_SET(从文件开始)/SEEK_END(从文件结束)/SEEK_CUR(从文件的当前位置)

注:文件锁不是锁定整个文件,而是锁文件的一部分。锁定的部分由l_whence

/l_start和l_len三个联合决定。

比如:l_whence选SEEK_SET,l_start=10,l_len=20。锁定区域是:第11个到

第30个

 

文件锁其实并不能锁定读写函数,读写的函数read()/write(),只能阻止其他进程的加锁行为,导致其他进程加不上锁。因此文件锁的正确用法是:在调用read()之前应该加一个读锁,在调用write()之前加一个写锁,读写完毕以后记得马上释放锁。

锁定的方式有两种,一种是F_SETLK,锁定失败立即返回-1,另一种是F_SETLKW,锁不上就一直等待,等到别人释放锁以后继续上锁。

F_GETLK 不是获得锁,是测试一个锁能不能加上,不会真的加锁。

 

3.7 access()函数

头文件

#include<unistd.h>

#include<fcntl.h>

int access(const char *pathname,int mode)

功能:判断文件的状态

描述:

pathname是文件名(包括路径),mode,模式包括四个宏:

R_OK 是否有读权限

W_OK 是否有写权限

X_OK 是否有执行权限

F_OK  文件是否存在

如果有或存在,返回0,取的是当前用户的权限

 

4、目录的操作

在Unix中,可以在程序里操作目录,包括:

1、新建目录,mkdir()

2、删除目录,rmdir()

3、切换当前目录,相当于cd命令,chdir()。

4、打开一个目录,opendir()

5、读取目录的内容(子项,子文件或子目录),readdir()

6、关闭已经打开的目录(不关闭也可以),closedir()

一般读取某个目录内容(子项)的步骤:

1、opendir()返回目录指针。

2、循环调用readdir(),注意读取每个子项。

3、closedir()关闭目录,这步可以省略。

 

5、目录操作的函数

5.1 mkdir()

头文件:

#include<sys/stat.h>

#include<sys/types.h>

int mkdir(const char* pathname,mode_t mode);

功能:创建一个新目录。

描述:pathname是要创建的目录路径,mode是该目录的权限,如果没有安全的要求,建议给”0777”。

返回,如果成功返回0,失败则返回-1.

 

5.2 rmdir()

头文件:

#include<unistd.h>

int rmdir(const char* pathname)

功能:删除一个目录

描述:

pathname是一个目录的路径

返回,如果成功,返回0,失败则返回-1.

 

5.3 chdir()

头文件:

#include<unistd.h>

int chdir(const char* path)

功能:切换当前工作目录

描述:

path是要改为的目录的路径

返回,如果成功,返回0,失败则返回-1.

 

5.4 opendir()

头文件:

#include<sys/types.h>

#include<dirent.h>

DIR* opendir(const * name)

功能:打开一个目录

描述:
name是目录的路径

返回,成功则返回该目录的指针,失败返回NULL,即0.

 

5.5 readdir()

头文件:

#include<dirent.h>

struct dirent* readdir(DIR* dirp)

功能:读取一个目录里面的子项。

描述:

dirp是目录的文件指针

如果成功,返回一个结构体指针,

struct dirent{

Ino_t d_ino;

Off_t d_off;

Unsigned short d_reclen;

Unsigned char d_type;

Char d_name[256];

}

如果失败,返回NULL。

 

5.6 closedir()

头文件:

#include<sys/types.h>

#include<dirent.h>

int closedir(DIR* dirp)

功能:关闭一个目录指针。

描述:

dirp是要关闭的目录指针。

返回,如果成功,返回0,失败返回-1.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一朝英雄拔剑起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值