标准I/O与文件I/O的区别:
文件操作:
? ? ? ? ?缓存 ? ? ? ? ? 操作对象 ? ? ? ? ? ? ? ?具体操作
标准IO ?全缓存/行缓存 ? 文件指针(流指针)FILE * ?1.打开 --fopen ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2.读写?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ?fgetc/fputc?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ?fgets/fputs?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ?fread/fwrite?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ? ?3.关闭?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ?fclose?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?4.定位?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ?fseek/ftell/rewind?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? ?
文件IO ?不带缓存 ? ? ? ?文件描述符 (整数) ? ? ? 1.打开 --open?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2.读写 --read/write
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?3.关闭 --close?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?4.定位 --lseek?
特性:
? ? ? ? .1 没有缓存区 (//可以认为数据直接交给了内核 )
?? ??? ?.2 操作对象不在是流(FILE *),而是文件描述符(整数)
?? ??? ?.3文件描述符
?? ??? ? ?很小的非负的整数?? ?int ? 0-1023
?? ??? ? ?内核每打开一个文件就会获得一个文件?? ?描述符? ?
?????????每个程序在启动的时候操作系统默认为其打开
?? ??? ? ???三个描述符与流对象匹配:
?? ??? ? ??????0 ==>STDIN_FILENO === stdin
?? ??? ? ???? ?1 ==>STDOUT_FILENO == stdout
?? ??? ? ??????2 ==>STDERR_FILENO == stderr
? ? ??
?? ??? ? ?stdin,stdout,stderr,===>FILE*
优缺点:
标准I/O:
优点:
- 缓冲:标准I/O使用了缓冲区,可以减少对文件的直接访问,提高性能。
- 格式化输出:标准I/O函数如
printf和scanf提供了强大的格式化功能,可以方便地处理格式化输入输出。 - 跨平台:标准I/O函数在大多数操作系统上都是可用的,提高了代码的可移植性。
缺点:
- 性能:与文件I/O相比,标准I/O可能会有额外的性能开销,因为它包含了额外的缓冲和格式化处理。
- 复杂性:标准I/O函数可能比文件I/O函数更复杂,需要更多的参数和错误处理。
文件I/O:
优点:
- 性能:文件I/O直接操作文件描述符,没有额外的缓冲和格式化处理,因此通常比标准I/O更快。
- 灵活性:文件I/O提供了更多的控制和灵活性,允许程序员直接操作文件和文件描述符。
- 无缓冲:文件I/O可以直接读写文件,无需缓冲区,这使得它可以用于处理非常大的文件或需要实时处理的数据。
缺点:
- 复杂性:文件I/O函数通常比标准I/O函数更复杂,需要更多的参数和错误处理。
- 格式化:文件I/O不提供格式化功能,需要程序员手动处理数据格式。
- 跨平台:文件I/O函数在不同的操作系统上可能有不同的行为,这降低了代码的可移植性。
一般在没有特殊要求的情况下,在linux下优先选择文件I/O
open()
1.open
?? ??? ?open("1.c",O_WRONLY|O_CREAT,0666 );
?? ??? ?
?? ??? ?int open(const char *pathname, int flags,int mode);
?? ??? ?功能:
?? ??? ??? ?获得一个文件描述符
?? ??? ?参数:
?? ??? ??? ?pathname:文件名
?? ??? ??? ?flags:
?? ??? ??? ?必须项:他们之间是互斥的,所以有且只能有一个?
?? ??? ??? ??? ?O_RDONLY
?? ??? ??? ??? ?O_WRONLY
?? ??? ??? ??? ?O_RDWR
?? ??? ??? ?可选项:
?? ??? ??? ?O_CREAT, 创建文件 ?//这个标志量存在,则需要指定参数 mode
?? ??? ??? ?O_EXCL, ?需要和O_CREAT同时使用,表示新建的文件不存在,成功,否则open就会失败
?? ??? ??? ?O_TRUNC ?文件内容清空
?? ??? ??? ?O_APPEND追加
?? ??? ??? ?
?? ? ? ? ? ?//后面
?? ??? ??? ?O_NOCTTY,不是终端设备
?? ??? ??? ?O_ASYNC 异步io,什么时候io不确定,
?? ??? ??? ?O_NONBLOCK 非阻塞?
一般在创建文件时,都加入截断操作,标准io中w=O_CREAT | O_WRONLY | O_TRUNC
write()
?? ?2.write
?? ??? ?char buf[1024];
?? ??? ?ssize_t write(int fd, ?const ?void *buf, size_t count);
?? ??? ?功能:
?? ??? ??? ?通过文件描述符向文件中写一串数据
?? ??? ?参数:
?? ??? ??? ?fd:文件描述符
?? ??? ??? ?buf:要写入文件的字符串的首地址
?? ??? ??? ?count:要写入字符的个数
?? ??? ?返回值:?
?? ??? ??? ?成功返回实际写入的个数
?? ??? ??? ?失败返回-1
read()
3.read
?? ??? ?ssize_t read(int fd, void *buf, size_t count);
?? ??? ?功能:
?? ??? ??? ?通过文件描述符读取文件中的数据
?? ??? ?参数:
?? ??? ??? ?fd:文件描述符
?? ??? ??? ?buf:存放数据空间的首地址
?? ??? ??? ?count:要读到数据的个数
?? ??? ?返回值:
?? ??? ??? ?成功返回读到数据的个数
?? ??? ??? ?失败返回-1
?? ??? ??? ?读到文件结尾返回0
lssek()
4.lseek? ==? fseek, rewind ftell
?? ??? ?off_t lseek(int fd, off_t offset, int whence);
?? ??? ?功能:
?? ??? ??? ?定位文件的位置
?? ??? ?参数:
?? ??? ??? ?fd:文件描述符
?? ??? ??? ?offset:偏移量
?? ??? ??? ??? ??? ??? ?正:向后偏移
?? ??? ??? ??? ??? ??? ?负:向前偏移
?? ??? ??? ??? ??? ??? ?零:不偏移
?? ??? ??? ?whence:
?? ??? ??? ??? ?SEEK_SET
?? ??? ??? ??? ?SEEK_CUR
?? ??? ??? ??? ?SEEK_END
?? ??? ??? ??? ? ? ? ? ? 正 空洞?
?? ??? ?返回值:
?? ??? ??? ?成功返回偏移量
?? ??? ??? ?失败返回-1
?? ??? ??? ?lseek(fd,0,SEEK_END);
文件描述符与流指针的转换:
filino:
int fileno(FILE *stream);
功能:
?? ?获得一个文件流指针中的文件描述符
参数:
?? ?stream:文件流指针
返回值:
?? ?成功返回文件描述符
?? ?失败返回-1
fdopen:
2.fdopen?? ?int fd -> FILE *fp
?FILE *fdopen(int fd, const char *mode);
?功能:
?? ?将文件描述符转化为文件流指针
?参数:
?? ?fd:已经打开的文件描述符
?? ?mode:
?? ??? ?"r"
?? ??? ?"r+"
?? ??? ?"w"
?? ??? ?"w+"
?? ??? ?"a"
?? ??? ?"a+"
?返回值:
?? ?成功返回文件流指针
?? ?失败返回NULL?? ?
TAG:io编程

客服1