⼩何讲Linux:基本⽂件操作和实例
⽂件操作的基本概念参见博客:
1.  函数说明
open()函数:是⽤于打开或创建⽂件,在打开或创建⽂件时可以指定⽂件的属性及⽤户的权限等各种参数。 所谓打开⽂件实质上是在进程与⽂件之间建⽴起⼀种连接,⽽“⽂件描述符”唯⼀地标识着这样⼀个连接
close()函数:是⽤于关闭⼀个被打开的⽂件。当⼀个进程终⽌时,所有被它打开的⽂件都由内核⾃动关闭,很多程序都使⽤这⼀功能⽽不显⽰地关闭⼀个⽂件。
read()函数:是⽤于将从指定的⽂件描述符中读出的数据放到缓存区中,并返回实际读⼊的字节数。若返回0,则表⽰没有数据可读,即已达到⽂件尾。读操作从⽂件的当前指针位置开始。当从终端设备⽂件中读出数据时,通常⼀次最多读⼀⾏。
write()函数:是⽤于向打开的⽂件写数据,写操作从⽂件的当前指针位置开始。对磁盘⽂件进⾏写操作,若磁盘已满或超出该⽂件的长度,则write()函数返回失败。
lseek()函数:是将⽂件指针定位到相应的位置。它只能⽤在可定位(可随机访问)⽂件操作中。管道、套接字和⼤部分字符设备⽂件是不可定位的,所以在这些⽂件的操作中⽆法使⽤lseek()调⽤。
2.  open()函数语法要点 所需头⽂件 #include <sys/types.h> /* 提供类型pid_t 的定义*/ #include <sys/stat.h>    /*记录⽂件状态头⽂件*/ #include <fcntl.h>        /*⽂件的控制,⽂件访问⽅式,读写权限的改变*/ 函数原型 int open(const char *pathname, int flags, int perms)
在操作⽂件之前,⾸先必须打开⽂件。open函数的打开原理就是将进程files_struct结构体和⽂件对象file相关联。
函数原型 int open(const char *pathname, int flags, int perms)
pathname :被打开的⽂件名(可包括路径名)。
flags :⽂件打开的⽅式(⽤下列⼀个或多个常数进⾏或运算构成定义,这些常数在fcntl.h 中定义) O_RDONLY :以只读⽅式打开⽂件O_WRONLY:以只写⽅式打开⽂件 O_RDWR:      以读写⽅式打开⽂件
O_CREAT:如果该⽂件不存在,就创建⼀个新的⽂件,并⽤第三个参数为其设置权限
O_EXCL:如果使⽤O_CREAT时⽂件已存在,则返回错误消息。这⼀参数可测试⽂件是否存在。此时open是原⼦操作,防⽌多个进程同时创建同⼀个⽂件
O_NOCTTY:使⽤本参数时,若⽂件为终端,则不将此设备分配作为此进程的控制终端
O_TRUNC:若⽂件已经存在,那么会删除⽂件中的全部原有数据,并且设置⽂件⼤⼩为0。
O_APPEND:以添加⽅式打开⽂件,在打开⽂件的同时,⽂件指针指向⽂件末尾,即将写⼊的数据添加到⽂件的末尾。
O_NONBLOCK 如果pathname指的是⼀个FIFO、⼀个块特殊⽂件或⼀个字符特殊⽂件,则该选项将此⽂件的本次打开操作和后续的I/O操作设置⾮阻塞⽅式。
O_SYNC 使每次write都等到物理I/O操作完成
flag参数可通过“| ”组合构成,但前3个标志常量(O_RDONLY、O_WRONLY 以及O_RDWR)不能相互组合。
perms被创建⽂件的存取权限(仅当创建新⽂件时才使⽤)
可以⽤⼀组宏定义:S_I(R/W/X)(USR/GRP/OTH)
其中R/W/X分别表⽰读/写/执⾏权限
USR/GRP/OTH分别表⽰⽂件所有者/⽂件所属组/其他⽤户
perms 是⽂件的存取权限,既可以⽤宏定义表⽰法,也可以⽤⼋进制表⽰法。
例如,S_IRUSR | S_IWUSR表⽰设置⽂件所有者的可读可写属性。⼋进制表⽰法中600也表⽰同样的权限
S_IRWXU-设置⽂件所有者具有全部权限。
函数返回值
成功:返回⽂件描述符(返回的⽂件描述符⼀定是最⼩的未⽤描述符数字)
失败:-1write的返回值
3.  close()函数语法要点 所需头⽂件
#include <unistd.h>
函数原型
int close(int fd)
函数输⼊值
fd:⽂件描述符
函数返回值
0:  成功
-1:出错
4.  read()函数语法要点
所需头⽂件:#include <unistd.h>
函数原型:ssize_t read(int fd, void *buf, size_t count)
参数:
fd:⽂件描述符
buf:指向存放读出数据的缓冲区的指针
count:指定读出的字节数
函数返回值
成功:读到的字节数
0:已到达⽂件尾
-1:出错(如以⾮阻塞⽅式打开的⽂件上⽆数据可读时)
注意:
有多种情况可使实际读到的字节数少于要求读的字节数:
读普通⽂件时,在读到要求字节数之前已到达了⽂件尾端。例如,若在到达⽂件尾端之前还有30个字节,⽽要求读100个字节,则read返回30,下⼀次再调⽤read时,它将返回0 (⽂件尾端)。
当从终端设备读时,通常⼀次最多读⼀⾏。
当从⽹络读时,⽹络中的缓冲机构可能造成返回值⼩于所要求读的字节数。
某些⾯向记录的设备,例如磁带,⼀次最多返回⼀个记录。
读操作从⽂件的当前位移量处开始,在成功返回之后,该位移量增加实际读得的字节数。
5.  write()函数语法要点
所需头⽂件:#include <unistd.h>
函数原型:ssize_t write(int fd, void *buf, size_t count)
参数:
fd:⽂件描述符
buf:指向存放待写⼊数据的缓冲区的指针
count:指定希望读出的字节数
函数返回值
成功:已写的字节数
出错:-1
在写普通⽂件时,写操作从⽂件的当前指针位置开始。
6.  lseek()函数语法要点 每个打开⽂件都有⼀个与其相关联的“当前⽂件位移量”。它是⼀个⾮负整数,对应从⽂件开始处计算的字节数,通常,读、写操作都从当前⽂件位移量处开始,并使位移量增加所读或写的字节数。系统默认:当打开⼀个⽂件时,除⾮指定O_APPEND 选择项,否则该位移量被设置为0。 所需头⽂件 #include <unistd.h> #include <sys/types.h> 函数原型:off_t lseek(int fd, off_t offset, int whence) 参数 fd:⽂件描述符 offset:偏移量,需要移动的距离,单位是字节,可正可负(向前移,向后移)
函数原型off_t lseek(int fd, off_t offset, int whence)
参数:
whence:基准位置
SEEK_SET:基准位置为⽂件的开头,新位置为偏移量的⼤⼩
SEEK_CUR:基准位置为⽂件指针的当前位置,新位置为当前位置加上偏移量
SEEK_END:基准位置为⽂件的结尾,新位置为⽂件的⼤⼩加上偏移量的⼤⼩
函数返回值 成功:⽂件的当前位移,该位移量⽤于下⼀个读或写操作。 出错:-1 lseek操作并不引起任何I/O操作,只是修改内核中的记录(修改的是已打开⽂件对象的f_pos字段) 7.  实例基本功能: 从⼀个⽂件(源⽂件)中读取最后10KB数据并到另⼀个⽂件(⽬标⽂件); 在实例中源⽂件是以只读⽅式打开; ⽬标⽂件是以只写⽅式打开(可以是读写⽅式); 若⽬标⽂件不存在,可以创建并设置权限的初始值为644,即⽂件所有者可读可写,⽂件所属组和其他⽤户只能读。 /*将⽂件src_file中的后10个字节的数据拷贝到dest_file⽂件中去,前提是src_file中已经准备好了数据*/ #include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include
<fcntl.h>#include <stdlib.h>#include <stdio.h> #define BUFFER_SIZE 15 /* 每次读写缓存⼤⼩,影响运⾏效率*/#define
SRC_FILE_NAME "src_file" /* 源⽂件名*/#define DEST_FILE_NAME "dest_file" /* ⽬标⽂件名⽂件名*/#define OFFSET 10 /* 复制的数据⼤⼩*/ int main(){ int src_file, dest_file; unsigned char buff[BUFFER_SIZE]; int real_read_len; /* 以只读⽅式打开源⽂件*/ src_file = open(SRC_FILE_NAME, O_RDONLY); if (src_file < 0 ) { printf("SRC_FILE Open error\n"); exit(1); } /* 以只写⽅式打开⽬标⽂件,若此⽂件不存在则创建该⽂件, 访问权限值为644 */ dest_file =
open(DEST_FILE_NAME,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (dest_file < 0) {
printf("DEST_FILE_NAME Open error\n"); exit(1); } /* 将源⽂件的读写指针移到最后10KB的起始位置*/ lseek(src_file, -OFFSET, SEEK_END); /* 读取源⽂件的最后10KB数据并写到⽬标⽂件中,每次读写1KB */ while ((real_read_len = read(src_file, buff,
sizeof(buff))) > 0) { write(dest_file, buff, real_read_len); } close(dest_file); close(src_file); return 0;} ⾸先编写源⽂件,在源⽂件中输⼊⼀串字符:(⼤于10个字节) 在终端中编译运⾏源程序: 在终端中使⽤cat命令输出⽬标⽂件中的内容: 打印变量real_read_len,显⽰的是10个字节: 读者可以看见,此处只从源⽂件拷贝了9个字节的内容到⽬标⽂件,我觉得应该是⽂件末尾的结束符eof占了⼀个字节,所以导致只显⽰了9个字节的数据,⽂件结束符eof为不可打印字符,未显⽰出来。 本⼈学识浅薄,如果⼤家知道其中的原因,还望不惜赐教。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。