文件i/o相关操作函数

文章目录

  • 一,文件描述符
  • 二,文件i/o相关函数
    • open()
    • creat()
    • close()
    • write()
    • read()
    • lseek()
    • dup()和dup2()
    • ioctl()
    • stat()
    • access()
    • unlink()
    • rename()
  • 三,文件夹操作

Linux系统中把一切都看做文件,Linux有7中类型文件:普通文件-、目录(dierectory)文件、符号(link)链接、字符 (character)设备文件、块(block)设备文件、管道(pipe)文件、套接字(socket)文件。其中文件、目录、符号链接会占用磁盘 空间来存储,而块设备、字符设备、套接字、管道是伪文件,并不占用磁盘空间.

当遇到不明白的函数都可以用man命令查询

man 手册第一部分是命令 man 1 printf
man 手册第二部分是系统调用 man 2 write
man 手册第三部分是库函数 man 3 printf

以下介绍的文件操作函数全部都属于系统调用函数

另外需要错误信息可以调用strerror()和perror()

perror(“Oen  failure”);
printf(“Open  failure: %s\n”, strerror(errno));

虽然perror使用简单,但是我们常用后者


一,文件描述符

对于内核而言,所有打开的文件、设备、网络socket都是通过文件描述符引用,文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,使用open或creat返回的文件描述符标识该文件,将其作为参数传给read或write。

应用程序运行的时候,系统将会为该进程默认打开三个文件描述符:
标准输入: STDIN_FILENO (0)
标准输出: STDOUT_FILENO (1)
标准出错: STDERR_FILENO (2)

文件描述符的变化范围是: 0~OPEN_MAX-1


二,文件i/o相关函数

open()

int open(const char *path, int oflag, *mode*);

返回值 int fd 文件描述符(file description), open系统调用返回的文件描述符一定是最小的、未使用的文件描述符数值。即3,因为0标准输入,1标准输出,2标准出错系统默认会打开。

参数:
1.*path: 要打开的文件、设备的路径名
2.**oflag: ** 由多个选项进行 或 运算构造oflag参数
必选:O_RDONLY (只读)、 O_WRONLY(只写)、 O_RDWR(读写)
可选:O_APPEND 每次写时都追加到文件的尾端。
O_CREAT 文件不存在则创建它,使用该选项需要第三个参数mode
O_NONBLOCK 如果path是一个FIFO、块设备、字符特殊文件则此选项为文件的本次打开和后续的I/O操作设置非阻塞模式方式。
O_TRUNC 如果文件存在,而且为只写或读写成功打开,则将其长度截取为0;
O_EXEC、O_SEARCH、O_CLOEXEC、O_NOCTTY…
3.mode: oflag带O_CREAT选项时,必须带该参数用来指定打开文件的权限模式,如066。

  • 例: int fd;
  • fd = open(“text.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
  • fd = open(“text.txt”, O_WRONLY|O_APPEND);
    其中fd就代表文件text.text

creat()

int creat(const char *path, mode_t mode);

此函数用来创建一个新文件并返回其fd。它等价于
open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);

  • 例: int fd;
    fd=creat(“text.txt”, 0644);

close()

int  close(int   fd);

该函数用来关闭一个打开的文件,关闭一个文件时还会释放该进程加在该文件上的所有记录锁。当一个进程终止时,内核自动关闭它所有打开的文件。

write()

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

如write成功,则返回实际写入的字节数,失败返回-1。

read()

ssize_t   read(fd,buf,sizeof(buf));

如果返回fd小于0说明读文件错误,可以用streror(errno)获取错位原因
如read成功,则返回读到的字节数。如已到达文件的尾端,则返回0。

read之前必须清空buff
menset(buf,0,sizeof(buff);
另外如果先使用了write()函数,要把文件偏移量(即光标位置)调到开头,这里用到 lseek()函数,下面介绍,或者在使用open()时加O_APPEND

lseek()

每打开一个文件时都有一个与其关联的“当前文件偏移量”。它通常是一个非负整数,用以度量从文件开始处计算的字节数。通常读写操作都是从当前文件偏移量处开始,并使用偏移量增加所读写的字节数。

按系统默认的情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0.

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

whence:
SEEK_SET, 则将该文件偏移量设置为距文件开始处offset个字节;
SEEK_CUR,则该文件的偏移量设置为当前值加offset,offset可为正或负;
SEEK_END,则将该文件偏移量设置为长度加offset,offset可正可负;

  • 例如
  • lseek(fd, 0, SEEK_END); 将文件偏移量设置到文件最后一个字节上;

dup()和dup2()

int  dup(int  fd);
int dup2(int fd, int fd2);
  • dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。
  • dup2可以用fd2参数指定新描述符的值。如果fd2已经打开,则先关闭。如fd等于fd2, 则dup2返回fd2, 而不关闭它。

例如

 int     fd = -1;
 fd = open(“std.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
 dup2(fd, STDOUT_FILENO);
 printf(“Hello Word!\n”);  //标准输出就会关闭,hello world会被输出重定向到文件fd即std.txt中

使用这两个函数可以用来实现标注输入、标准输出、标准出错重定向

ioctl()

ioctl()函数一直是I/O操作的杂物箱,不能用本章中其他函数表示的I/O操作通常都能用ioctl()表示。终端I/O、设备I/O是使用ioctl()最多的地方。

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

fd: 文件描述符
cmd: 命令字,这个参数需要与设备驱动中的cmd保持一致。
第三个参数可选

stat()

这两个函数都是用来返回文件或目录的相关信息,
只是stat()的第一个参数是文件名,
而fstat()的第一个参数是文件打开的相应文件描述符。

int stat(const char * restrict path, struct  stat *restrict buf);
int fstat(int fd, struct stat *buf);
  • 例如
  • struct stat stbuf; stat(“stat.c”, &stbuf);

access()

access可以用来测试文件是否存在或测试其权限位:

int access(const char *path, int mode);
  • mode: F_OK、R_OK、W_OK、X_OK

例子1 测试文件是否存在:
if( !(access(“test.txt”, F_OK)) ) // 返回0表示存在;返回-1表示不存在。
{
printf(“File exist\n”);
}

例子2 测试文件是否可读可写:
if( !(access(”test.txt”, R_OK|W_OK)) ) // 返回0表示存在;返回-1表示不存在。
{
printf(“File mode is read/write \n”);
}

unlink()

int unlink(const char *path);

该系统调用可以用来删除文件
调用该函数将path指定的文件的链接数减1,如果对该文件还有其他链接存在,则仍可以通过其他链接访问该文件的数据。
只有当链接记数达到0时,该文件的内容才可被删除。如果有进程打开了该文件,其内容也不能被删除。关闭一个文件时,内核首先检查打开该文件的进程个数,如果这个记数达到0,内核再去检查它的链接记数,如果记数也是0,那么就删除该文件内容。

rename()

int  rename(const char *oldname, const char *newname);

调用该函数可以实现文件的重命名。


三,文件夹操作

创建文件夹:

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(IDR *dp);

改变工作目录:

int chdir(const char * pathname);

你可能感兴趣的:(笔记)