Linux下编程-----文件与IO(一)基本API
来源:互联网 发布:js map参数传递 编辑:程序博客网 时间:2024/06/11 04:01
I/O是什么
输入/输出是内存和外设之间拷贝数据的过程:
设备->内存: 输入操作
内存->设备: 输出操作
高级I/O: ANSI C提供的标准I/O库函数成为高级I/O, 也称为带缓冲的I/O;
低级I/O: Linux 提供的系统调用, 通常也称为不带缓冲的I/O;
文件描述符
在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在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));// res: fileno(stdin)=0}
基本API
1.open
打开成功返回文件描述符;打开失败返回-1。
int open(const char *pathname, int flags, mode_t mode);
参数:
pathname: 文件名, 可以包含[绝对/相对]路径名;
flags: 文件打开模式;
mode: 用来指定对文件所有者, 文件用户组以及系统中的其他用户的访问权限;
#include <string.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <dirent.h>#define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ }while(0)int main(){ int fd; umask(0); fd=open("test.txt",O_RDONLY,0666); if(fd==-1) ERR_EXIT("open failure"); printf("Open OK!\n"); return 0;}
注意两点:
1.我们使用#define定义出错的函数,这样更加专业
2.umask是从我们定义的权限中再“拿走”相应的位,注意这里是逻辑减。我们定义权限666,系统一般默认umask是022(使用umask命令查看),所以剩下的是644,我们也可以将umask的值置为0,这样在程序中就不受其影响了。
2.close
int close(int fd);
关闭文件描述符, 使得文件描述符得以重新利用,一个进程结束时也会主动关闭所有的文件。
3.read
ssize_t read(int fd, void *buf, size_t count);
返回从文件复制到缓冲区的字节数,count:从该文件复制到buf的字节个数。
4.write
ssize_t write(int fd, const void *buf, size_t count);
返回值:
错误: -1
什么都没做: 0
成功: 返回成功写入文件的字节数
注意:
write返回大于0时, 并不代表buf的内容已经写入到磁盘上的文件中了, 其仅仅代表buf中的数据已经copy到相应的内核缓冲区了. 要实现将缓冲区的内容真正”冲洗”到磁盘上的文件, 需要调用fsync函数;
int fsync(int fd);
其将内核缓冲区中尚未写入磁盘的内容同步到文件系统中;
其实在open调用的时候也可以指定同步选项:O_SYNC O_SYNC The file is opened for synchronous I/O. Any write(2)s on the resulting file descriptor will block the calling process until the data has been physically written to the underlying hardware.
write会等到将buf的内容真正的写入到磁盘才真正返回;
#define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ }while(0)int main(){ int fd; umask(0); fd=open("test.txt",O_RDONLY,0666); if(fd==-1) ERR_EXIT("open failure"); printf("Open OK!\n"); int outfd; outfd=open("temp.txt",O_RDWR | O_CREAT,0666); if(outfd==-1) { ERR_EXIT("open dest error"); } char buff[1024]; int nread; while((nread=read(fd,buff,1024))>0) write(outfd,buff,nread); close(fd); close(outfd); return 0;}
实现了简单的cp功能。
5.lseek
off_t lseek(int fd, off_t offset, int whence);
Whence取值:
SEEK_SET
The offset is set to offset bytes.
SEEK_CUR
The offset is set to its current location plus offset bytes.
SEEK_END
The offset is set to the size of the file plus offset bytes.
int ret =lseek(fd,0,SEEK_CUR); printf("current offset =%d\n",ret);
6。目录访问之opendir,readdir
DIR *opendir(const char *name); //打开一个目录
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp); //关闭目录
int mkdir(const char *pathname, mode_t mode); //创建目录
int rmdir(const char *pathname); //删除一个空目录
struct dirent { ino_t d_ino; /* inode number */ off_t d_off; /* not an offset; see NOTES */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file; not supported by all filesystem types */ char d_name[256]; /* filename */ };
成功: 返回一个指向dirent结构的指针, 它包含指定目录的下一个连接的细节;
失败:NULL
DIR* dir=opendir("."); struct direnn *de; while((de=readdir(dir))!=NULL) { if(strncmp(de->d_name,".",1)==0) continue; printf("%s\n",de->d_name); closedir(dir); exit(EXIT_SUCCESS);
上面代码的功能是实现简单的ls操作,列出目录下的普通文件。
- Linux下编程-----文件与IO(一)基本API
- linux系统编程-文件与IO(一)
- Linux下编程-----文件与IO(二)stat函数
- Linux下编程------文件与IO(三) 文件共享和fcntl函数
- Linux下C编程入门笔记——文件IO操作(一)
- Unix网络编程--文件IO(1) 基本API
- 嵌入式 Linux系统编程(一)——文件IO
- Linux系统编程-文件IO(一)
- 文件IO编程一
- [Linux网络编程]socket编程学习(一)——基本API
- Linux下的socket编程实践(二)socket编程基本API简介
- Linux下的socket编程实践(二)socket编程基本API简介
- Linux文件IO编程
- linux下的文件io编程实现文件的拷贝
- Linux系统编程(2)——文件与IO之系统调用与文件IO操作
- Linux文件---文件IO编程
- linux下编程的gcc编译中关于头文件与库文件搜索路径相关问题(一)
- LINUX 下,编程自学一:文件操作
- C语言hash函数
- USACO 1.3 Mixing Milk
- 树中最长路径 树形DP HDU 3534 Tree
- STM32 无线下载程序(非IAP)
- iOS开发问题之the file “XXX” could not be opened because you don't have permission to view it
- Linux下编程-----文件与IO(一)基本API
- NOIP2014解方程
- 轻松python之文件专题-关于目录树的一些操作
- 算法 练习1.1
- 【手势识别-论文学习】 Hands Deep in Deep Learning for Hand Pose Estimation
- 逆波兰:将中缀表达式转为后缀表达式
- 给定M*N矩阵,编写代码找出某元素
- 【树链剖分】 HDU 4729 An Easy Problem for Elfness 二分
- 使用对象去暂停或锁住一个线程的方式