文章目录
全文约 11560 字,预计阅读时长: 33分钟
系统调用I/O接口
至今所学的文件操作,无外乎读取和写入;而文件包含:文件本身所具有的属性,和文件的内容。而对文件的操作,都是进程对文件的操作。语言层库函数对硬件的操作必须经过OS的系统调用。
几乎所有的语言层面都默认打开这些接口,因为都有输入输出的需求,便于语言刚开始的学习上手使用;否则会是这样的场景:在学习这门语言之前呢,铁子们先来学一下打开文件…
- 库函数 vs 系统调用接口:
fopen --> open
fclose --> close
fread --> read
fwrite --> write
- 查看进程属性的当前路径:每个进程都有一个内置的属性
cwd
ps axj | greap t1
ll /proc/t1ID
C文件操作
- C 库函数
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
把 ptr 所指向的数组中的数据写入到给定流 stream 中。- 参数:你期望写入多少个 size,从哪个数组写入到哪个 文件 里。
- 返回值:实际上写入了几个size;
- 一般 size 设置大一点,count 设置小一点。
char * buf[1024];
int wf = fwrite(buf,sizeof(buf),1,stdout);
- 打开文件的
w
写入 :每次写入都是重新写入;意味着之前的文件内容,会被清空。打开文件的a
写入:追加写入,不清空原始文件内容,在文件最后进行写入,数据增多的过程。 - C语言默认打开三个文件流:
stdin键盘文件
,stdout / stderr显示器文件
。这三个流的类型都是FILE*
, fopen返回值类型,文件指针。 - C 库函数
int fprintf(FILE *stream, const char *format, ...)
发送格式化输出到流 stream 中。如果成功,则返回写入的字符总数,否则返回一个负数。
fprintf(stdout,"%d , %c\n",24,a);
Linux文件I/O介绍
open
函数说明:
(1) int open(const char *pathname, int flags);
(2) int open(const char *pathname, int flags, mode_t mode);
- 返回值:打开文件成功,那么返回文件描述符
fd (file descriptor)
,值大于或等于0;失败,-1。 - 参数:
pathname
是文件路径,可以是相对路径(即不以 “/” 开头),也可以是绝对路径(即以 “/” 开头)。flags
:宏标志位,使用时包含一种访问模式:O_RDONLY
(只读)、O_ WRONLY
(只写)或O_RDWR
(读写)。mode
:文件的权限设置。当参数flags
指定标志位O_CREAT
或O_TMPFILE
的时候,必须指定参数 mode。可以用八进制文件掩码设置。
- 当文件不存在时,
O_CREAT
与上述三种任意一种访问模式进行 ‘或’ 运算.。flags
:宏标志位,这些参数只占一个int整形中的一个比特位。读:00;写:01;…
int fd = open("t1.txt",O_ WRONLY|O_CREAT,0644);
if(fd<0)
{
perroe("open");
return 1;
}
close(fd)
write
:函数说明:ssize_t write(int fd, const void *buf, size_t count);
- buf 写入哪个 fd 的文件,写多少个字节进去。
int fd = open("t1.txt",O_ WRONLY|O_CREAT,0644);
if(fd<0)
{
perroe("open");
return 1;
}
const char* msg = "hello write\n";
write(fd,msg,strlen(msg));
close(fd);
read
函数:ssize_t read(int fd, void *buf, size_t count);
- 从fd文件读取到buf里,读取多大字节
- 因文件不按字符串的规定,所以读取时,应读 buf大小-1个的字节。最后一位设置成 \0 .
- 返回值:读取到的字节大小。返回0,则表示读到了文件末尾。
char buf[1024];
ssize_t s = read(fd,buf,sizeof(buf)-1)
if(s>0)
{
buf[s]='\0';
printf("%s\n",buf);
}
O_APPEND
:追加写入
int fd = open(t1.txt,O_WRONLY|O_APPEND);
- 系统调用接口要兼容自身语法特性,使用成本较高,且不具备可移植性。C语言会自动根据平台,选择自己底层对应的文件接口。
FD文件描述符-file descriptor
fd 是连续的整数;输入输出错误占了0,1,2。操作系统会把进程打开的多个文件管理起来。文件本身是一个 struct file
的结构,内含有读写方法,和内核缓冲区。OS则用打开的文件指针通过struct file_struct
内的一个文件指针数组的方式进行管理。
用户层看到的fd,其实是系统中维护进程和文件对应关系的数组下标,也就是说进程是用PCB里的一个指针这样的接口进行所有的文件操作。缓冲区里的数据通过文件描述符写入对应的目标文件中。
FD的使用规则:找到当前没有被使用的最小的一个下标,作为新的文件描述符。 close
现在的含义代表: 断开 struct file_struct
里对应下标的文件指针指向,随后那块文件资源由OS接受处理,释放资源或加入闲置队列。
所有语言层面的默认打开文件,都是底层系统支持的,默认一个进程运行的时候,就打开了0,1,2.
/* open file information */
struct files_struct *files;
语言层的FILE
- FILE 是一个结构体,内部含有:底层对应的文件描述符下标;应用层,C语言提供的缓冲区数据
//缓冲区相关
/* The following pointers correspond to the C++ streambuf protocol. */
/* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+