Linux学习笔记之四(文件IO、目录IO)

1、文件IO

1.1、open and close

使用以下代码查看以下open函数原型:

man 2 open

在这里插入图片描述
如图,open函数有两个原型,分别是:

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

其中

pathname:文件所在的路径。
flag:文件给用户的权限。
mode:对新创建的文件赋予的权限。
返回值:一个文件描述符,以整数的形式体现,成功打开则返回3,4,5其中一个,失败则返回-1。

flag的参数有以下这些,可以用" | "(或逻辑)同时选择多个。当选择到O_CREAT的时候,必须添加第三个参数mode。下面这些参数具体意义还得查看手册(manual)。

必选:O_RDONLY, O_WRONLY, O_RDWR
可选:O_CLOEXEC, O_CREAT,  O_DIRECTORY,  O_EXCL,  O_NOCTTY,  O_NOFOLLOW,  O_TMPFILE

mode参数一般是四位数,第一位数表示八进制(不管它,输入0即可)。后面三位数分别表示用户权限,同组用户权限,其他用户权限。用rwx表示权限,然后1/0表示是否开启该权限,最后将其组合转化为八进制。如下:

rwx: read write execute
111(rwx)->7,110(rw-)->6....(二进制转换)

0000(000 000 000: --- --- ---)
0001(000 000 001: --- --- --x)
0002(000 000 010: --- --- -wx)
...
0777(111 111 111: rwx rwx rwx)

但所创建的文件真实的权限还要和umask码取反后相与,可以输入umask查看其具体值:
在这里插入图片描述
最后是close函数,就相对非常简单多了。把open返回的文件描述符号作为输入参数即可。

close(fd);
note: fd is a file descriptor 

1.2、read and write

先查看以下函数原型:

man 2 read

在这里插入图片描述
如图,其函数原型是:

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

fd:文件描述符。
*buf:指向读取的内容的指针 。
count:要读取的字节数 。
返回值:如果读取成功,则返回读取的字节数目。如果失败,返回-1;如果正常读取,但没读取到东西,返回0。

再来看看write函数。依旧先看manual。

man 2 write

在这里插入图片描述
函数原型是:

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

fd:文件描述符。
*buf:指向写入缓冲区的内容的指针 。
count:要写入的字节数 。
返回值:如果写入成功,则返回写入的字节数目。如果失败,返回-1;如果正常写入,但没写入任何东西,则返回0。

注意的地方:

  1. 如果write的第一个参数是为1,则意为把缓冲区的东西写入终端,而非写入文件。

1.3、lseek

老生常谈,先看一些它的函数说明。

man 2 lseek

在这里插入图片描述
可以看出,其函数原型是;

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

fd:文件描述符。
offset:指针偏移的量 。
whence:指针偏移的基准位置。(可选的参数有:SEEK_SET, SEEK_CUR, SEEK_END…)
返回值:如果写入成功,则返回所指向的字节数。如果失败,则返回-1。

这里有几个点需要说明:

  1. 无论是ssize_t,还是off_t之类的,其实都属于整形数据。所以在一般情况下,把他们当整形用即可。
  2. 文件的读写操作都是依靠指针的偏移来确定位置的。譬如当你读完或写完N个字节,该指针也会随之偏移到第N位去,直到文件被close指针才复位。
  3. 默认打开文件的时候,文件指针指向定0个字节。

1.4、综合练习

  • 练习任务:
    • 在“/home/yuquan”下创建并打开一个test.c文件
    • 往该文件写入“writing successfully!”的字符串
    • 将该字符串读取并打印出来。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
	char buf_read[21] = {0};

	int fd = open("/home/yuquan/test.c",O_RDWR|O_CREAT, 0777);
	
	write(fd, "writing successfully!\n", 22);
	
	lseek(fd,-22,SEEK_CUR);		//让指针从新指向文件开头
	
	read(fd, buf_read, 21);

	printf("the string you read is:%s\n",buf_read);

	close(fd);
	
	return 0;
}

上面这段代码去掉了很多检查报错冗余代码,一般来说不建议这样写,而是像下面这样写好些。
在这里插入图片描述

2、目录IO

2.1、mkdir

查看函数说明:

man 2 mkdir

在这里插入图片描述
可以看到函数原型是:

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

*pathname:将被创建的文件所在的目录。
mode:给该文件的权限,参考文件IO小节的open中的mode,原理是一样的。
返回值:成功返回0,失败返回-1。

2.2、opendir, closedir, readdir

opendir的函数说明在manual第三页,所以应该输入以下指令来查找。

man 3 opendir

在这里插入图片描述
可以看到函数原型有两个,分别是:

DIR *opendir(const char *name);
DIR *fdopendir(int fd);

name:文件的名称(包含路径)。
fd:文件的描述符,配合文件IO中的open函数使用。
返回值:如果正确打开文件,则返回一个文件流指针,反之返回NULL。

文件流指针是一个指向文件的指针,在初始时刻,它指向的是打开该文件夹之后的第一个文件。
接着,再来看看closedir函数:

man 3 closedir

在这里插入图片描述

DIR *dirp:目录流指针。
返回值:成功返回0,失败返回-1。

最后说一下readdir

man 3 readdir

在这里插入图片描述
函数原型是:

struct dirent *readdir(DIR *drip);

DIR * dirp:文件流指针。
返回值:成功读取返回一个结构体,失败返回NULL。

readdir函数读完一个文件之后,文件流指针会接着往下偏移,直到该文件夹里的所有文件被读取完毕且返回NULL。接着细说一下这个结构体,从使用手册可以看出它的结构长这样:

struct dirent {
   ino_t          d_ino;       /* inode number */
   off_t          d_off;       /* not an offset; see NOTES */
   unsigned short d_reclen;    /* length of this record */
   unsigned char  d_type;      /* type of file; not supported
                                  by all filesystem types */
   char           d_name[256]; /* filename */
};

比较重要的参数有以下两个,其中的d_ino指的是文件的编号,比如我输入ls -i之后看到的数字:
在这里插入图片描述

d_name[256]指的是所读文件的名称,比如下面这些:
在这里插入图片描述

2.3、综合练习

  • 练习任务:
    • j键盘输入一个目录,并且将该目录中的所有文件都打印到终端里来。
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int mian(int argc, char *argv[])
{
        struct dirent *temp;
        if(argc != 2)
        {       
                printf("using:%s <directory name>\n",argv[0]);
        }
        DIR *drip = opendir(argv[1]);
        int i = 0;
        while((temp=readdir(dirp)) != NULL)
        {
                i++;
                printf("the %d file name is: %s \n",i,temp->d_name);
        }
        closedir(dirp);
        return 0;
}

注意:遍历文件只能有一个层级,不能遍历文件中的文件。因为文件流指针只指向该文件的下一层级。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

__TAT__

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

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

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

打赏作者

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

抵扣说明:

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

余额充值