首页 > 系统相关 >Linux文件IO之二 [补档-2023-07-21]

Linux文件IO之二 [补档-2023-07-21]

时间:2024-01-13 17:15:29浏览次数:34  
标签:返回 文件 函数 int 补档 st 描述符 Linux 07

8-5 linux系统IO函数:

open函数:

函数原型int open(const char *pathname, int flags, mode_t mode);

功能:打开一个文件并返回文件描述符。与c库中的fopen差不多

参数

pathname:要打开的文件路径名。

flags:打开文件的标志

O_RDONLY(只读)

O_WRONLY(只写)

O_RDWR(读写)

O_CREAT(创建文件)

O_APPEND(追加写)

mode(可选):新文件的访问权限,只有在创建新文件时才会使用。一般使用八进制表示.

0400:只读权限,允许文件所有者读取。

0200:只写权限,允许文件所有者写入。

0100:执行权限,允许文件所有者执行(对于可执行文件)。

0040:允许组成员读取。

0020:允许组成员写入。

0010:允许组成员执行(对于可执行文件)。

0004:允许其他用户读取。

0002:允许其他用户写入。

0001:允许其他用户执行(对于可执行文件)。

这些权限可以通过使用按位或运算符(|)来进行组合。

返回值:成功时返回文件描述符,失败时返回-1。

close函数:

函数原型int close(int fd);

功能:关闭一个已打开的文件。

参数:fd为要关闭的文件描述符。

返回值:成功时返回0,失败时返回-1。

​ 如果一个进程打开了某个文件,如果这个进程终止了,那么系统会自己调用clos函数关闭这些个已经 打开的文件。

read函数:

函数原型ssize_t read(int fd, void *buf, size_t count);

功能:从文件中读取数据。

参数

​ fd:要读取的文件描述符。

​ buf:用于存储读取数据的缓冲区指针。

​ count:要读取的字节数。

返回值:返回实际读取的字节数,若返回0表示已达到文件末尾,失败时返回-1。

write函数:

函数原型ssize_t write(int fd, const void *buf, size_t count);

功能:向文件中写入数据。

参数

​ fd:要写入的文件描述符。

​ buf:要写入的数据缓冲区指针。

​ count:要写入的字节数。

返回值:返回实际写入的字节数,失败时返回-1。

lseek函数:

头文件

#include<sys/types.h>

#include<unistd.h>

函数原型:off_t lseek(int fd , off_t offset , int whence);

功能:在文件读写操作中设置文件指针的偏移量。

参数

​ fd: 文件描述符

​ offset: 文件偏移量

​ whence:位置

SEEK_SET: 如果offset为0则代表是文件的开始位置

SEEK_CUR: 如果offset为0则代表当前位置

SEEK_END: 如果offset为0则代表文件的结尾位置

返回值:调用成功则返回从当前位置到开始的长度,调用失败则返回-1,

一. lseak函数的一些用法:

​ 移动文件读写位置:如果我们使用write函数往文件中写入了内容,然后调用read函数进行读文件, 会发现没有读到刚才写入的内容。那是因为当我们输入完毕以后,读写位置此时是在刚才输入的内容之后的, 因此什么也读不到,所以我们可以使用lseek函数将读写位置往回移一下。请在合适的位置调用以下函数。

lseek(fd , 0 , SEEK_SET); //将读写位置移动到文件首部。

二. 计算文件大小:因为lseek函数的返回值是offset到whence的大小。请在合适的位置调用以下函数。

lseek(fd , 0 , SEEK_END); //返回值为从0到文件末尾之间有多少字节

三. 拓展文件大小:lseek的偏移量大小是以offset到whence之间决定的(函数会相对于文件首部来计算, 也是就是说offset可以看作首部),如果我们将whence设置为文件末尾,offset我们设置为大于0的数,那么 在计算偏移量的时候就会向文件尾再偏移offset个字节,然后我们再写入offset个字节的数据,这样我们就可 以用来扩展文件的大小了。可以尝试在合适的位置调用以下函数:

lseek(fd , 10 , SEEK_END); //先扩展

write(fd , “a” , 1); //再写入

perror函数和errno:

头文件:#include<errno.h>

函数原型:void perror(const char* str);

功能:当系统调用出错时,系统会对errno自动赋值,perror可以将errno对应的错误信息打印出来。

参数

可以传入全局变量 “errno” 来打印相应的错误信息。

errno****变量:他在头文件<errno.h>中,当系统调用某个函数失败后会对该变量进行设置,相应的错误代码 会存储在该变量中。

8-6 文件IO的阻塞和非阻塞:

阻塞文件IO:当一个进程,线程或者其他什么东西对文件进行某些操作时,如果还有一个进程,线程或其 他什么东西也想对同一个文件进行操作。那么会将后面想要操作的进程,线程或者其他东西等阻塞,直到没有 东西对文件进行操作时,才可以去操作文件。

非阻塞文件IO:当一个进程,线程或者其他什么东西对文件进行某些操作时,如果还有一个进程,线程或 其他什么东西也想对同一个文件进行操作,那么后来的会直接返回,不会阻塞。

注意:如果多个进程,线程或者其他东西同时访问一个文件时,会触发竞争条件。linux多个线程,进程或 者其他东西访问同一个文件时,如果这个文件是普通文件则是非阻塞的,如果是终端设备或者管道和套接字那 就是阻塞的。

stat函数:

头文件:

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

函数原型:int stat(const char *path , struct stat *buf);

功能:通过文件路径来获取文件的相关信息,并且存储在结构体struct stat中.如果文件是个链接文件的话,那么会获取链接文件所指向的文件的信息

参数

​ path: 要获取文件信息的文件路径。

​ buf: 用于存储文件信息的结构体指针。

返回值

​ 成功时返回0,失败则返回-1。

lstat函数:

头文件

include <sys/types.h>

include <sys/stat.h>

include <unistd.h>

函数原型:int lstat(const char *path , struct stat *buf);

功能:通过文件路径来获取文件的相关信息,并且存储在结构体struct stat中.如果文件是个链接文件的话,那么会获取链接文件的信息,而不是获取链接文件指向的文件的信息。

参数

​ path: 要获取文件信息的文件路径。

​ buf: 用于存储文件信息的结构体指针。

返回值

​ 成功时返回0,失败则返回-1。

stat/lstat获取的stat结构体信息:

struct stat {

dev_t st_dev; // 文件的设备编号

ino_t st_ino; // 文件的 i-node 编号

mode_t st_mode; // 文件的类型和访问权限

nlink_t st_nlink; // 连接到该文件的硬链接数量

uid_t st_uid; // 文件所有者的用户 ID

gid_t st_gid; // 文件所有者的组 ID

dev_t st_rdev; // 如果文件是设备文件,则为其设备编号

off_t st_size; // 文件大小(以字节为单位)

blksize_t st_blksize; // 文件系统 I/O 缓冲区的优化大小

blkcnt_t st_blocks; // 分配给文件的块数

struct timespec st_atim; // 最后访问时间

struct timespec st_mtim; // 最后修改时间

struct timespec st_ctim; // 最后状态更改时间

};

stat结构体中成员变量mode_t st_mode;** 代表的是文件的类型和访问权限,它一共有16位:

0-2bit – 其他人权限:

S_IROTH 00004 读权限

S_IWOTH 00002 写权限

S_IXOTH 00001 执行权限

S_IRWXO 00007 掩码, 过滤 st_mode中除其他人权限以外的信息

3-5bit – 所属组权限:

S_IRGRP 00040 读权限

S_IWGRP 00020 写权限

S_IXGRP 00010 执行权限

S_IRWXG 00070 掩码, 过滤 st_mode中除所属组权限以外的信息

6-8bit – 文件所有者权限:

S_IRUSR 00400 读权限

S_IWUSR 00200 写权限

S_IXUSR 00100 执行权限

S_IRWXU 00700 掩码, 过滤 st_mode中除文件所有者权限以外的信息

12-15bit – 文件类型:

S_IFSOCK 0140000 套接字

S_IFLNK 0120000 符号链接(软链接)

S_IFREG 0100000 普通文件

S_IFBLK 0060000 块设备

S_IFDIR 0040000 目录

S_IFCHR 0020000 字符设备

S_IFIFO 0010000 管道

S_IFMT 0170000 掩码,过滤 st_mode中除文件类型以外的信息

目录打开函数opendir:

头文件:#include<dirent.h>

函数原型:DIR *opendir(const char *dirname);

函数功能:打开一个目录,并且返回一个DIR结构体指针。

函数参数:dirname是要打开的目录的路径名。

函数返回值:调用成功后返回一个指向DIR结构体的指针,如果调用失败则返回NULL。

条目读取函数readdir:

​ 头文件:#include<dirent.h>

函数原型:struct dirent *readdir(DIR *dirp);

函数功能:读取目录中的文件或者子目录,一次调用只读取一个。

函数参数:dirp是函数opendir返回的目录流指针。

函数返回值:调用成功后返回一个指向struct dirent结构体的指针,如果调用失败或者读取到目录末尾则 返回NULL。

struct dirent****结构体的内容:

struct dirent{

ino_t d_ino; //文件的 inode 号。

off_t d_of;://文件在目录流中的偏移。

unsigned short d_reclen; //该条目的长度。

unsigned char d_type; //文件类型。

char d_name[]; //文件名。

}

其中成员变量 d_type 是一个用于表示文件的类型,以下为它的取值:

DT_UNKNOWN:未知类型。

DT_REG:普通文件。

DT_DIR:目录。

DT_FIFO:命名管道(FIFO)。

DT_SOCK:套接字。

DT_CHR:字符设备。

DT_BLK:块设备。

DT_LNK:符号链接

目录关闭函数closedir:

头文件:#include<dirent.h>

函数原型:int closedir(DIR *dirp);

函数功能:关闭先前opendir打开的目录。

函数参数:dirp是原先opendir打开的目录流指针。

函数返回值:调用成功后返回0,调用失败返回-1.

以上三个目录函数的例子:

dup函数:

头文件#include<unsitd.h>

函数原型:int dup(int oldfd);

函数功能:赋值一个已有的文件描述符,并且返回一个新的文件描述符,这个新的文件描述符与原来的文件描述符指向同一个资源或者文件。

函数参数:oldfd为要赋值的旧的文件描述符。

返回值:成功则返回新的文件描述符,这个新的描述符与旧的所指向的文件或者资源是一样的。失败则返回-1.

dup2函数:

头文件#include<unsitd.h>

函数原型:int dup2(int oldfd , int newfd);

函数功能:将一个已有的文件描述符赋值到指定的文件描述符中,如果指定的文件描述符已经打开了一个文件,则会先关闭它,然后再将旧的文件描述符复制到这个位置。

函数参数

​ oldfd为要赋值的旧的文件描述符。

​ newfd 为要指定的新文件描述符

返回值:成功则返回新的文件描述符,失败则返回-1。

注意:dup2函数可以用于重定向标准输入,输出和错误流(描述符表的0 1 2号元素)。

fcntl函数:

头文件:#include<fcnt1.h>

函数原型:int fcnt1(int fd , int cmd , …);

函数功能:对文件描述符进行各种控制操作。

函数参数

​ fd 是要操作的文件描述符

​ cmd 是要执行的命令:

​ F_DUPFD:复制文件描述符。

​ F_GETFD:获取文件描述符标志。

​ F_SETFD:设置文件描述符标志。

​ F_GETFL:获取文件状态标志。

​ F_SETFL:设置文件状态标志。

​ … 这个是与命令相关的附加参数,更具命令的不同来进行传递。

返回值:返回值取决于命令,如果调用失败则返回-1.

标签:返回,文件,函数,int,补档,st,描述符,Linux,07
From: https://www.cnblogs.com/xiaobai1523/p/17962576

相关文章

  • Linux的进程管理 [补档-2023-07-25]
    Linux进程管理9-1并发与并行:​并发:在同一个cpu上,并且在一个时间段时,同时运行多个程序。比如在1000毫秒内,我们有5个程序需要执行,所以我们可以将1000毫秒分为5个200毫秒,让每个程序都占用200毫秒的cpu使用权,这样在1000毫秒内就可以执行5个程序。​并行:大于等......
  • GDB调试程序 [补档-2023-07-19]
    gdb调试​它是gcc的调试工具,调试工具都能干什么就不多说了。7-1生成调试信息​在使用gcc编译c/c++的程序时,需要在编译命令中加入-g这一参数,它可以为你显示函数名,变量名等待。例如:gcc-gtest.c-otest​7-2启动gdb调试信息​启动指令:gdb可执行程序......
  • Linux文件IO之一 [补偿-2023-07-21]
    Linux文件IO8-1C标准库IO函数的工作流程​使用fopen函数打开一个文件,之后会返回一个FILE*fp指针,fp指针指向一个结构体,这个结构体是c标准io库中的一个结构体,这个结构体有三个重要的成员:文件描述符:描述符指向一个打开文件表,通过此表可以找到文件的inode表,通过对应的in......
  • MakeFile文件的使用 [补档-2023-07-13]
    makefile-gdb文件​可以在文件中指定那些文件可以先进行编译,那些文件可以后进行编译,那些文件可以重新编译。他可以自动化编译程序。。。。6-1makefile基本规则​如下:​目标:依赖​(tab)命令​规则三要素:目标:要生成的目标文件。依赖:目......
  • Linux下的gcc/g++编译器的使用 [补档-2023-06-13]
    gcc编译器​这东西是Linux上的c/c++编译器。5-1gcc的工作流程5-2gcc的常用参数-v查看gcc版本号,--version也可以-E生成预处理文件-S生成汇编文件-c只编译,生成.o文件,通常称为目标文件-I指定头文件所在的路径-L指定库文件所在的路径-l指定库的名......
  • Linux系统的一些实用操作 [补档-2023-07-30]
    Linux的实用操作4-1.常用快捷键强制停止:当某些程序运行时,或者命令输入错误时,可以通过ctrl+c来强制结束当前的操作。退出或登出:当我们要退出某些用户时,或者要退出某些特殊的页面可以使用ctrl+d来进行。(vi/vim不可用)历史命令搜索:通过输入history命令来查看之前输入......
  • Linux的用户和权限 [补档-2023-07-07]
    Linux用户和权限3-1.su用户切换命令exit用户退出命令​用户切换命令的语法:​su[-][用户名]​其中:​-可选,表示是否在切换用户后加载环境变量,建议带上。​用户名可选,表示要切换到那个用户,如果不填则默认切换到root用户上。​......
  • Linux 系统开机启动项清理
    通常情况下,你能用 /etc/init.d 查看系统引导时启动的服务项。但是systemd会用不一样的展现方式,下面是一些命令,用于展示开机启动时的进程项。你可以看到,这里头有一项是蓝牙,我不需要使用它,那么我应该怎样关闭并阻止它在开机时后启动?完成上面的操作之后,用下面的命令来确定自己是否......
  • vi / vim编辑器的使用 [补档-2023-07-01]
    vi/vim编辑器​vi/vim编辑器是linux中的文本编辑器,其中vim比vi的功能更加强大,可以编辑shell程序,推荐使用vim,下面也将介绍vim如何使用。2-1vi/vim的三种工作模式命令模式​在此模式下,所敲的每一个键都是一个命令,不可以进行文本编辑。比如输入w代表保存等待。输入......
  • 详解Linuxrc、rcS、rc.local、Profile
    /Linuxrc执行init进程初始化文件。主要工作是把已安装根文件系统中的/etc安装为ramfs,并拷贝/mnt/etc/目录下所有文件到/etc,这里存放系统启动后的许多特殊文件;接着Linuxrc重新构建文件分配表inittab;之后执行系统初始化进程/sbin/init。/mnt/etc/init.d/rcS完成各个文件系统的......