unix_c--IO学习

IO简单来说就是对文件的操作
IO的使用有两种:
1 系统调用
2 库函数的调用

系统调用和库函数的区别:

系统调用:
移植性:
系统调用是内核的直接调用,移植性差,或者说,无移植性。
库函数兼容性好,脱离了系统平台,对与不同的系统实现的方式不一样
效率:
系统调用会直接使用内核,效率高,响应快,但是可能会占用内核,一般建议少用
库函数是非直接的调用
联系:
库函数的实现也是调用了系统调用,库函数封装了不同系统对系统调用的
差异,也拓展了一些功能。
使用范围:
虽然库函数封装了大部分的系统调用,但是有的功能也只能由系统调用来完成。

文件描述符

对内核而言,所有打开的文件都通过文件描述符引用。文件描述符是一个非负
整数。当打开一个现有的文件或这创建一个新文件时,内核向进程返回一个文
件描述符号。

系统调用

open和opennat

1
2
3
#include <fcntl.h>
int open(const char *path, int oflag, ..../*mode_t mode*/);
int openat(int fd, const char *path, int oflag, .../*mode_t mode */);

打开一个文件,并返回文件描述符
当path是绝对路径,openat的fd参数就会被忽略,openat函数就相当于open
当path参数指定的是相对路径名,fd参数指出了相对路径名在文件系统中的
开始地址。
oflag的值可以同时指定多个,是以按位或的形式来传递多个参数
参数都可以从man page来查看
O_RDONLY 只读打开
O_RWONLY 只写打开
O_RDWR 读、写打开
O_EXEC 只执行打开
O_SEARCH 只搜索打开(应用于目录)
O_APPEND 每次写文件都追加到文件的末尾
O_CREAT 如果文件不存在则创建它。
O_EXCL 如果指定了O_CREAT,若文件已经存在则出错(可以用来判断文件是否存在)
……..

creat

用来创建一个新文件

1
2
3
#include <fcntl.h>

int creat(const char *path, mode_t mode);

creat的功能就是创建一个文件,mode来指定文件的权限
但是creat创建文件之后是以只写方式打开创建的文件。
如果创建文件之后写了文件又要读取文件,就必须先close然后在open

close

1
2
3
#include <unistd.h>

int close (int fd);

关闭一个已经打开的文件

lseek

1
2
3
#include <unistd.h>

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

用来改变文件偏移量的位置
whence用来指定改变偏移的方式
SEEK_SET 文件的偏移量设置为距文件开始处offset个字节
SEEK_CUR 文件的偏移量设置为但前值加上offset,offset可正可负
SEEK_END 文件的偏移量设置为文件长度加offset,offset可正可负

read

1
2
3
#include <unistd.h>

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

read函数用来从打开的文件中读取文件
将打开的文件的nbytes个读到buf指向的内存

write

1
2
3
#include <unistd.h>

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

write函数是向打开的文件写入数据
将buf指向的内存中的数据,写入到打开的文件中

IO库函数

打开流

1
2
3
4
5
#include <stdio.h>

FILE *fopen(const char *restrict pathname, const char *restrict type);
FILE *freopen(const char *restrict pathname, const char *restrict type, FILE *restrict fp);
FILE *fdopen(int fd, const char *type);

(1)fopen函数用来打开路径名为pathname的文件
(2)freopen在一个指定的流上打开指定的文件,若原来流打开的,就先关闭该流。
若该流已经定向,则使用freopen清除该定向
(3)将文件描述符和标准I/O流相结合

读和写流

一次读取一个字符,若成功就返回

1
2
3
4
5
#include <stdio.h>

int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);

将字符压回送回流

1
int ungetc(int c, FILE *fp);

返回值:若成功, 返回c,若出错,返回EOF

1
2
3
4
5
#include <stdio.h>

int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);

返回值:若成功,返回c,若出错,返回EOF

1
2
3
#include <stdio.h>
char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *gets(char *buf);

格式化I/O

格式化输出

1
2
3
4
5
6
7
#include <stdio.h>

int printf(const char *restrict format, ...);
int fprintf(FILE *restrict fp, const char *restrict format, ...);
int dprintf(int fd, const char *restrict format, ...);
int sprintf(char *restrict buf, const char *restrict format, ...);
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);

格式化输入

1
2
3
4
#include <stdio.h>
int scanf(const char *restrict fomat, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(const char *restrict buf, const char *restrict format, ...);

3个函数的返回值:赋值的输入函数;若输入出错或在任一转换前已经达到文件尾端,返回EOF

Contents
  1. 1. 文件描述符
  • 系统调用
    1. 1. open和opennat
    2. 2. creat
    3. 3. close
    4. 4. lseek
    5. 5. read
    6. 6. write
  • IO库函数
    1. 1. 打开流
    2. 2. 读和写流
    3. 3. 格式化I/O
  • ,