i/o 设备在linux中被当作啥文件,步步LINUX C--文件I/O操作

熟悉linux系统的同学都知道,所有的设备在linux下都被当作文件来处理,因此了解文件的I/O操作是十分重要的。

1/具体来说,有以下几种文件类型(控制台ls -l命令的第一列即为文件类型):

符号

类型

符号

类型

s

套接字文件

d

目录文件

l

链接文件

b

块设备文件

c

字符设备文件

p

管道文件

-

普通文件 另外,有几个特殊的文件,标准输入,标准输出,标准出错

类型

文件描述符

说明

标准输入

0

它是命令的输入,默认是键盘,也可以是文件或其他命令的输出。使用'

标准输入

1

它是命令的输出,默认是屏幕,也可以是其他文件。使用'>'或'1>'符号进行重定向。

标准出错

2

它是命令出错信息的输出,默认是屏幕,也可以是其他文件。使用'2>'符号进行重定向。

2/LINUX通过文件权限,来管理文件的读/写/执(wrx)行权限。

3/文件操作函数总结:

在开始列写具体函数之前,我们首先列出文件I/O中的常用参数表:

flag参数(头文件:fcntl.h)

取值

含义

O_RDONLY

以只读方式打开文件

O_WRONLY

以只写方式打开文件

O_RDWR

以读写方式打开文件

O_CREAT

若要打开的文件不存在,则创建一个。权限在mode参数中说明

O_EXCL

与O_CREAT配合使用以验证一个文件是否存在

O_TRUNC

如果文件存在,且以只读或只写方式打开,则将其长度截短为0

O_NOCTTY

如果文件描述符指向终端设备,则不将此设备分配为此进程控制终端

O_APPEND

写入时追加到文件结尾

O_NONBLOCK

将后续的I/O操作设置为非阻塞方式

O_NONELAY

功能不那么完善的O_NONBLOCK

O_SYNC

只有数据被写入外存或其他设备之后操作才返回

mode参数(头文件:fcntl.h)

取值

八进制

含义

S_ISUID

04000

设置用户识别号

S_ISGID

02000

设置组号

S_SVTX

01000

粘贴位

S_IRUSR

00400

文件所有者的读权限位

S_IWUSR

00200

文件所有者的写权限位

S_IXUSR

00100

文件所有者的执行权限位

S_IWGRP

00040

该组用户的读权限位

S_IRGRP

00020

该组用户的写权限位

S_IXGRP

00010

该组用户的执行权限位

S_IROTH

00004

其他组用户的读权限位

S_IWOTH

00002

其他组用户的写权限位

S_IXOTH

00001

其他组用户的执行权限位

S_IRWXU

00600

文件所有者的读+写+执行权限

S_IRWXG

00060

该组用户的读+写+执行权限

S_IRWXO

00006

其他组用户的读+写+执行权限

whence参数(头文件:sys/types.h)

取值

含义

SEEK_SET

将该文件的位移量设置为距文件开始处offset个字节处

SEEK_CUR

将该文件的位移量设置为距当前位置offset个字节处。offset可正可负。

SEEK_END

将该文件的位移量设置为距文件结尾处offset个字节处offset可正可负。

cmd参数(头文件:fcntl.h)

取值

相应操作

F_DUPFD

复制一个现存文件描述符

F_GETFD

获得文件描述符

F_SETFD

设置文件描述符

F_GETFL

获得文件状态标志

F_SETFL

设置文件状态标志

F_GETOWN

获得异步I/O权

F_SETOWN

设置异步I/0权

F_GETLK

获得记录锁

F_SETLK

设置记录锁,不等待

F_SETLKW

设置记录锁,必要时等待

下面是文件操作的函数以及功能的简单描述:

文件描述符的I/O操作

打开函数

#include#include#includeint open( const char * pathname, int flags);

int open( const char * pathname,int flags, mode_t mode);

两个函数在成功后都返回文件描述符,以用作后续操作,并且将该文件的引用计数器值加1;出错返回-1。mode参数可以直接使用八进制表示。

创建函数

#include int creat(const char *pathname, mode_t mode);

成功则返回文件描述符,以用作后续操作;出错返回-1。创建成功后以只写方式打开文件。

creat函数等效于open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

如果想创建后以读写方式打开,则

open(pathname, O_RDWR | O_CREAT | O_TRUNC, mode);

关闭函数

#includeint close(int fd);

成功后该文件的引用计数器值减1,并且返回0;出错返回-1。

定位函数

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

成功后返回新的文件偏移量;出错返回-1。offset为正数时向后移动,为负数时向前移动。

读函数

#include ssize_t read(int fd, void *buf, size_t nbytes);

成功后返回读取到的字节数;出错返回-1。

读谱通文件:读到nbytes之前已经达到文件结尾,则返回读到的字节数。下一次调用时返回0;

读终端设备:通常一次最多读一行;

读网络设备:网络中的缓冲限制可能造成实际读取的字节数小于nbytes;

读面向记录的设备:一次只能读一个字符。

写函数

#include ssize_t write(int fd, const void *buf, size_t nbytes);

成功后返回写入的字节数;出错返回-1。

write+lseek可以产生空洞文件。

文件的属性操作

在学习文件属性操作函数的时候,我们会发现很多函数的名称十分熟悉。这些不是控制台的命令吗?没错,控制台就是通过调用这些函数实现指定的shell命令。

修改权限

#include #include int chmod(const char *pathname, mode_t mode);

int fchmod(int fd, mode_t mode);

两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。

使用者需具有对该文件的所有权或者为ROOT用户方可操作成功。

修改所有者

#include #include int chown(const char *pathname,uid_t owner,gid_t group);

int fchown(int fd,uid_t owner,gid_t group);

int lchown(const char *pathname,uid_t owner,gid_t group);

前两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。

lchown更改链接文件本身的所有者而不是所指向文件的所有者。

修改文件名

#includeint rename(const char *oldfname, const char *newfname);

成功后返回0;出错返回-1。

若oldfname指向普通文件且newfname存在指向普通文件,则newfname文件被删除,重命名成功。如果newfname存在指向目录文件,出错。

若oldfname指向目录文件且newfname存在指向目录文件,则newfname文件被删除,重命名成功。如果newfname存在指向普通文件,出错。

修改文件长度

#include#includeint truncate(const char * pathname,off_t len);

int ftruncate(int fd,off_t len);

两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。

修改文件性质

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

fcntl的返回值与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列三个命令有特定返回值:F_DUPFD,F_GETFD,F_GETFL以及F_GETOWN。第一个返回新的文件描述符,第二个返回相应标志,最后一个返回一个正的进程ID或负的进程组ID。

文件的其他操作

文件状态

#include #include int stat(const char *pathname, struct stat *buf);

int fstat(int fd, struct stat *buf);

int lstat(const char *pathname, struct stat *buf);

前两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。

lstat函数返回链接文件的相关信息,而不是所指向文件的相关信息。

文件描述符操作

#include int dup (int fd);

int dup2(int fd, int fd2);

两个函数复制文件描述符,成功后都返回新的文件描述符;出错返回-1。

这个函数通常用来重定向,例如dup2(fd,1),可将输出重定向到文件描述符所指文件。

同步函数

#include void sync(void);

int fsync(int fd) ;

成功后返回0;出错返回-1。用于强制将系统缓存区内容写入文件。

目录函数

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

int rmdir(const char* pathname);

DIR *opendir(const char *pathname);

struct dirent *readdir(DIR *dp);

int closedir(DIR *dp);

成功后返回0;出错返回-1。

rmdir函数只能用于删除空目录。

工作目录

#include int chdir(const char *path );

int fchdir(int fd);

char *getcwd(char *buf, size_t size);

前两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。

getcwd函数用于获取当前工作目录。size要足够容纳这个字符串。

链接文件

#include #include int link(const char *pathname1, const char *pathname2);

int unlink(const char *pathname);

int remove(const char *pathname);

int symlink(const char *actualpath, const char *sympath);

int readlink(const char *pathname, char *buf, int bufsize);

前四函数成功后返回0;出错返回-1。readlink函数成功后返回读取字节数;出错返回-1。

link函数用于创建硬链接,symlink用于创建符号链接。

至此文件I/O操作基本总结完毕。一些特殊的文件,管道文件会在进程通信中谈到,套接字文件会在网络编程中谈到。

(完)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值