文件I/O实践(1)

文件描述符

对于Linux内核而言,所有的文件或设备都对应一个文件描述符(Linux的设计哲学:一切皆文件),这样可以简化系统编程的复杂程度;

当打开/创建一个文件的时候,内核向进程返回一个文件描述符(是一个非负整数).后续对文件的操作只需通过该文件描述符即可进行,内核记录有关这个打开文件的信息;

一个进程启动时,默认已经打开了3个文件,标准输入(0,STDIN_FILENO),标准输出(1,STDOUT_FILENO),标准错误输出(2,STDERR_FILENO),这些常量定义在unistd.h头文件中;

其中,文件描述符基本上是与文件描述指针(FILE*)一一对应的,如文件描述符0,1,2对应stdin,stdout,stderr;

文件指针与文件描述符的转换

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

intfileno(FILE*stream);

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

FILE*fdopen(intfd,constchar*mode);

//示例int main(){cout << "fileno(stdin) = " << fileno(stdin) << endl;cout << "fileno(stdout) = " << fileno(stdout) << endl;cout << "fileno(stderr) = " << fileno(stderr) << endl;return 0;}文件I/OAPI

1.open

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);

参数:

pathname:文件名,可以包含[绝对/相对]路径名;

flags:文件打开模式;

mode:用来指定对文件所有者,文件用户组以及系统中的其他用户的访问权限;

注意:newMode=mode&~umask

flags常用值

//示例1int main(){int fd = open("test.txt", O_RDONLY);if (fd == -1){cerr << "file open error, errno = " << errno <<"\nstrerror: " << strerror(errno) << endl;perror("perror");exit(EXIT_FAILURE);}cout << "file open success" << endl;}//示例2inline void err_exit(std::string message){perror(message.c_str());exit(EXIT_FAILURE);}int main(){umask(0000);int fd = open("test.txt", O_RDWR|O_CREAT|O_EXCL, 0666);if (fd == -1)err_exit("file open error");elsecout << "file descriptor = " << fd << endl;}

[附]

(1).umaskAPI

//改变umask值

mode_tumask(mode_tmask);

(2).ulimit-a

查看系统中的各种限制;

其中-n:查看一个进程所能够打开的最大文件数

(3).cat/proc/sys/fs/file-max

查看一个系统能够支持的最大打开文件数(该数与内存大小有关)

2.close

#include <unistd.h>int close(int fd);

write会等到将buf的内容真正的写入到磁盘才真正返回;

//示例: 带有O_SYNC选项int main(int argc, char *argv[]){if (argc < 3){cerr << "Usage : " << argv[0] << " src dest" << endl;exit(EXIT_FAILURE);}int infd = open(argv[1], O_RDONLY);if (infd == -1)err_exit("file O_RDONLY error");int outfd = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC|O_SYNC, 0666);if (outfd == -1)err_exit("file O_WRONLY error");char buf[1024];int readBytes, writeBytes;while ((readBytes = read(infd, buf, sizeof(buf))) > 0){writeBytes = write(outfd, buf, readBytes);cout << "readBytes = " << readBytes<< ", writeBytes = " << writeBytes << endl;}}文件的随机读写

5.lseek

对应于C库函数中的fseek,通过指定相对于当前位置,末尾位置或开始位置的字节数来重定位currp:

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

返回值:新的文件偏移值;

Whence取值:

SEEK_SET

Theoffsetissettooffsetbytes.

SEEK_CUR

Theoffsetissettoitscurrentlocationplusoffsetbytes.

SEEK_END

怎么能研究出炸药呢?爱迪生不经历上千次的来自失败,怎么能发明电灯呢

文件I/O实践(1)

相关文章:

你感兴趣的文章:

标签云: