Unix网络编程--文件IO(1) 基本API

来源:互联网 发布:飞扬软件官网 编辑:程序博客网 时间:2024/06/05 04:28

什么是I/O
输入/输出是内存和外设之间拷贝数据的过程:
设备->内存: 输入操作
内存->设备: 输出操作
高级I/O: ANSI C提供的标准I/O库函数成为高级I/O, 也称为带缓冲的I/O;
低级I/O: Linux 提供的系统调用, 通常也称为不带缓冲的I/O;

文件描述符
在网络编程中,我们经常会得到监听套接字描述符已连接套接字描述符。而当我们打开文件就会获得文件描述符,它是个很小的正整数。每个进程在PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。一个进程启动时,默认打开了3个文件,标准输入、标准输出、标准错误,对应的文件描述符是0(STDIN_FILENO)、1(STDOUT_FILENO)、2(STDERR_FILENO),这些常量定义在unistd.h头文件中。注:括号内的就代表文件指针File*。
文件描述符和文件指针的转换函数:

fileno: 将文件指针转换成文件描述符

int fileno(FILE *stream);

fdopen: 将文件描述符转换成文件指针

FILE *fdopen(int fd, const char *mode);
int main()  {      printf("fileno(stdin)= %d\n",fileno(stdin));      /*fileno(stdin)=0*/  }   

基本API

基本API,就是要从最基本的说起,现在我们先来明白freadread的区别:
fread返回的是一个FILE结构指针,而read返回的是一个int的文件描述符,前者fopen/fread的实现是靠调用底层的open/read来实现的.

fopen/fread
是C标准的库函数,操作的对象是:file stream

open/read
是和操作系统有关的系统调用。操作的对象是:file descriptor

简单一点说,f是ANSI的C标准库,后面的是UNIX下的系统调用,如果要和底层硬件打交道,必须是后面的!

1.open/fopen
打开成功返回文件描述符;打开失败返回-1。
int open(const char *pathname, int flags);

pathname: 文件名, 可以包含[绝对/相对]路径名;
flags: 文件打开模式

这里写图片描述

#include <sys/stat.h> #include <fcntl.h> // 包含close所需要的头文件 #include <unistd.h> int main(int argc, char *args[]) { // 以只读方式打开一个存在的文件    int fd1 = open("a.txt", O_RDONLY);    printf("fd1 = %d\n", fd1);    close(fd1);   // 以只读方式打开一个不存在的文件    int fd2 = open("b.txt", O_RDONLY);    printf("fd2 = %d\n", fd2);   close(fd2); return 0;  }

notes:fd1的值为-1,fd2的值为3,由于文件描述符0、1、2已经默认存在了,因此,新打开的文件的文件描述符是从3开始的。

#include<stdio.h>FILE * fopen(const char * path,const char * mode);/*文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开失败则返回NULL,并将错误代码存在error中*/

2.close/fclose

int close(int fd);

关闭文件描述符, 使得文件描述符得以重新利用,一个进程结束时也会主动关闭所有的文件。

int fclose(FILE * stream);

fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。

3.read/fread

ssize_t read(int fd, void *buf, size_t count);/*ssize_t 是int型(无符号整型),占4个字节,在64位计算机系统中,ssize_t是long int 型,占8个字节*/

返回从文件复制到缓冲区的字节数,count:从该文件复制到buf的字节个数。

ssize_t fread(void * ptr,ssize_t size,ssize_t count,FILE * stream);/*fread() 用来从文件流中读取数据,返回实际读取到的count数目*/

stream:已打开的文件指针
ptr:指向欲存放读取进来的数据空间,读取的字符数以参数size*count来决定

4.wirte/fwrite

ssize_t write(int fd, const void *buf, size_t count);  /*write返回大于0时, 并不代表buf的内容已经写入到磁盘上的文件中了, 其仅仅代表buf中的数据已经copy到相应的内核缓冲区高速缓冲*/
ssize_t fwrite(const void * ptr,size_t size,size_t count,FILE * stream);

5.iseek/fseek

off_t lseek(int fd, off_t offset, int whence); /*off_t是一个long的类型别名*/
int fseek(FILE *stream, long offset, int fromwhere);/*fseek 用于二进制方式打开的文件,移动文件读写指针位置*/

stream为文件指针;offset为偏移量,整数表示正向偏移,负数表示负向偏移;origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2:
fseek(fp,100L,0):把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1):把fp指针移动到离文件当前位置100字节处;
fseek(fp,100L,2):把fp指针退回到离文件结尾100字节处。

参考博文:
http://www.cnblogs.com/liuliunumberone/archive/2011/05/06/2038628.html
http://blog.csdn.net/nk_test/article/details/48215061

0 0
原创粉丝点击