Linux应用编程(文件IO基础)

1.1、个简单的文件 IO 示例

#include 
#include 
#include 
#include 
int main(void)
{
 char buff[1024];
 int fd1, fd2;
 int ret;
 /* 打开源文件 src_file(只读方式) */
 fd1 = open("./src_file", O_RDONLY);
 if (-1 == fd1)
 return fd1;
 /* 打开目标文件 dest_file(只写方式) */
 fd2 = open("./dest_file", O_WRONLY);
 if (-1 == fd2) {
 ret = fd2;
 goto out1;
 }
 /* 读取源文件 1KB 数据到 buff 中 */
 ret = read(fd1, buff, sizeof(buff));
 if (-1 == ret)
 goto out2;
 /* 将 buff 中的数据写入目标文件 */
 ret = write(fd2, buff, sizeof(buff));
 if (-1 == ret)
 goto out2;
 ret = 0;
out2:
 /* 关闭目标文件 */
 close(fd2);
out1:
 /* 关闭源文件 */
 close(fd1);
 return ret;
} 

1.2、文件描述符

调用 open 函数会有一个返回值,该返回值就是一个文件描述符。文件描述符数字最大值为 1023(0-1023)。每次给打开的文件分配文件描述符都是从最小的没有被使用的文件描述符(0~1023)开始,当之前打开的文件被关闭之后,那么它对应的文件描述符会被释放,释放之后也就成为了一个没有被使用的文件描述符了。

1.3、open 打开文件

#include 
#include 
#include 

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

open 函数即可传入 2 个参数(pathname、flags)、也可传入 3 个参数(pathname、flags、mode),但是第三个参数 mode 需要在第二个参数 flags 满足条件时才会有效。

函数参数和返回值含义如下:

pathname:字符串类型,用于标识需要打开或创建的文件,可以包含路径(绝对路径或相对路径)信息,譬如:“./src_file”(当前目录下的 src_file 文件)、"/home/dengtao/hello.c"等;如果 pathname 是一个符号链接,会对其进行解引用。

flags:调用 open 函数时需要提供的标志,具体如下:
Linux应用编程(文件IO基础)_第1张图片
在这里插入图片描述
mode:此参数用于指定新建文件的访问权限,只有当 flags 参数中包含 O_CREAT 或 O_TMPFILE 标志时才有效(O_TMPFILE 标志用于创建一个临时文件)。可通过 chmod 命令对文件权限进行修改,使用"ls -l"命令来查看到文件所对应的权限。

权限表示方法如下所示:
Linux应用编程(文件IO基础)_第2张图片
我们从低位从上看,每 3 个 bit 位分为一组,分别表示:
O—这 3 个 bit 位用于表示其他用户的权限;
G—这 3 个 bit 位用于表示同组用户(group)的权限,即与文件所有者有相同组 ID 的所有用户;
U—这 3 个 bit 位用于表示文件所属用户的权限,即文件或目录的所属者;
S—这 3 个 bit 位用于表示文件的特殊权限,文件特殊权限一般用的比较少,这里就不给大家细讲了。

例:
111000000(二进制表示):表示文件所属者具有读、写、执行权限,而同组用户和其他用户不具有任何权限;

使用 open 函数打开一个指定的文件(譬如/home/dengtao/hello),如果该文件不存在则创建该文件,创建该文件时,将文件权限设置如下:
文件所属者拥有读、写、执行权限;
同组用户与其他用户只有读权限。
使用可读可写方式打开:

int fd = open("/home/dengtao/hello", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (-1 == fd)
	return fd;

1.4、write 写文件

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

函数参数和返回值含义如下:

fd:文件描述符。关于文件描述符。
buf:指定写入数据对应的缓冲区。
count:指定写入的字节数。
返回值:如果成功将返回写入的字节数(0 表示未写入任何字节),如果此数字小于 count 参数,这不是错误,譬如磁盘空间已满,可能会发生这种情况;如果写入出错,则返回-1。

1.5、read 读文件

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

函数参数和返回值含义如下:
fd:文件描述符。与 write 函数的 fd 参数意义相同。
buf:指定用于存储读取数据的缓冲区。
count:指定需要读取的字节数。
返回值:如果读取成功将返回读取到的字节数,实际读取到的字节数可能会小于 count 参数指定的字节数,也有可能会为 0,譬如进行读操作时,当前文件位置偏移量已经到了文件末尾。

1.6、close 关闭文件

#include 
int close(int fd);

函数参数和返回值含义如下:
fd:文件描述符,需要关闭的文件所对应的文件描述符。
返回值:如果成功返回 0,如果失败则返回-1。

1.7 lseek

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

函数参数和返回值含义如下:
fd:文件描述符。
offset:偏移量,以字节为单位。
whence:用于定义参数 offset 偏移量对应的参考值,该参数为下列其中一种(宏定义):
SEEK_SET:读写偏移量将指向 offset 字节位置处(从文件头部开始算);
SEEK_CUR:读写偏移量将指向当前位置偏移量 + offset 字节位置处,offset 可以为正、也可以为负,如果是正数表示往后偏移,如果是负数则表示往前偏移;
SEEK_END:读写偏移量将指向文件末尾 + offset 字节位置处,同样 offset 可以为正、也可以为负,如果是正数表示往后偏移、如果是负数则表示往前偏移。

返回值:成功将返回从文件头部开始算起的位置偏移量(字节为单位),也就是当前的读写位置;发生错误将返回-1。

使用示例:
(1)将读写位置移动到文件开头处:

off_t off = lseek(fd, 0, SEEK_SET);
if (-1 == off)
return -1;

(2)将读写位置移动到文件末尾:

off_t off = lseek(fd, 0, SEEK_END);
if (-1 == off)
return -1;

(3)将读写位置移动到偏移文件开头 100 个字节处:

off_t off = lseek(fd, 100, SEEK_SET);
if (-1 == off)
return -1;

(4)获取当前读写位置偏移量:

off_t off = lseek(fd, 0, SEEK_CUR);
if (-1 == off)
return -1;

函数执行成功将返回文件当前读写位置

你可能感兴趣的:(LinuxC编程(文件io,网络编程...),linux,运维,linux应用开发)