文件I/O
快速对齐
- Esc//进入命令模式
- GG//回到起始位置
- v//进入可是模式
- shift+g//全选
- =//快速对齐
sscanf & sprintf
int sscanf(const char *str, const char *format, …);
int sprintf(char *str, const char *format, …);
- 功能:按format格式对str指向的字符数组进行I/O操作
- 返回:成功返回I/O的字节数,失败返回EOF
#include<stido.h>
int main(void)
{
double a = 0.0;
char b[20] = " ";
int c = 0;
char q[20] = " ";
char *p = "12.2 张三 24";
sscanf(p,"%f %s %d",&a,b,&c);
sprintf(q,"%f %s %d",a,b,c);
printf("%.2f,%s,%d\n",a,b,c);
return 0;
}
I/O 系统调用
- 全缓存
- 磁盘文件
- 全缓存满了
- fflush
- 磁盘文件
- 行缓存
- 标准输入输出
- 行缓存满了
- ‘\n’
- fflush
- 标准输入输出
- 无缓存
- 标准错误流
- perror
- 标准错误流
文件常用系统调用
open()
- int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
- 功能:打开或创建一个文件
- 返回:成功返回文件描述符,失败返回-1
- open函数的flags参数,O_RDONLY、O_WRONLY或O_RDWR 与多个可选模式按位或操作
- O_RDONLY:以只读方式打开
- O_WRONLY:以只写方式打开
- O_RDWR :以读写方式打开
- O_APPEND:文件以追加模式打开在写以前,文件读写指针被置在文件的末尾
- O_CREAT:若文件不存在将创建一个新文件.新文件的权限由mode决定,例:0765
- O_EXCL :通过O_CREAT,生成文件 , 若文件已经存在,则open出错,调用失败.若是存在符号联接,将会把它的联接指针的指向文件忽略.
- O_TRUNC:假如文件已经存在,且是一个普通文件,打开模式又是可写,就把文件的长度设置为零,丢弃其中的现有内容.若文件是一个FIFO或终端设备文件,O_TRUNC标志被忽略
- O_DIRECTORY:假如pathname不是目录, 打开就失败
- O_NONBLOCK 或 O_NDELAY:打开(open) 文件可以以非块(non-blocking) 模式打开.此时文件并没有打开,也不能使用返回的文件描述符进行后续操作,而是使调用程序等待
- create()
- int creat(const char *pathname, mode_t mode);
- 功能:创建一个新的文件,
- 返回:成功返回描述符并以只读方式打开文件,失败返回-1
- close()
- int close(int fd);
- 功能:关闭一个打开的文件
- 返回:若成功为0 ,若出错为-1
- read()
- ssize_t read(int fd, void *buf, size_t count);
- 功能:从打开文件中读数据
- 返回:读到的字节数,若已到文件尾为0 ,若出错为-1
- write()
- ssize_t write(int fd, const void *buf, size_t count);
- 功能: 向打开的文件中写数据
- 返回:若成功为已写的字节数,若出错为-1
- lseek()
- off_t lseek(int fd, off_t offset, int whence);
- 功能:定位一个已打开的文件
- 返回:若成功则返回新的文件位移量( 绝对偏移量) ,若出错为-1
- fcntl()
- int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock); - 功能:可以改变已经打开文件的性质
- 复制一个现存的描述符, 新文件描述符作为函数值返(cmd=F_DUPFD)
- 获得/设置文件描述符标志(cmd= F_GETFD或F_SETFD)
- 获得/设置文件状态标志(cmd = F_GETFL或F_SETFL)
- 获得/设置文件锁(cmd = F_SETLK、cmd = F_GETLK、 F_SETLKW)
-
- 第三个参数为struct flock结构体
- 返回:若成功则依赖于cmd ,若出错为-1
- cmd的常见取值
- F_DUPFD:复制文件描述符,新的文件描述符作为函数返回值返回
- F_GETFD/F_SETFD:获取/设置文件描述符,通过第三个参数设置
- F_GETFL/F_SETFL:获取/设置文件状态标志,通过第三个参数设置。
可以更改的几个标志是:O_APPEND, O_NONBLOCK, SYNC,
O_ASYNC(O_RDONLY、O_WRONLY和O_RDWR不适用)
- int fcntl(int fd, int cmd);
- fdopen()
- FILE *fdopen(int fd, const char *mode);
- 功能:文件描述符=> 文件指针(fd=>FILE*)
- fileno()
- int fileno(FILE *stream);
- 功能:文件指针=> 文件描述符(FILE*=>fd)
- 标准文件指针
- stdin -》0
- stdout -》 1
- stderr -》2
设置缓存setbuf & setvbuf
- setbuf
- void setbuf(FILE *stream, char *buf);
- 功能:流缓冲操作,setbuf 总是使用非最优的缓冲大小,应当避免使用它。
- 返回:无
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(void)
{
setbuf(stdout,NULL);
int i = 0;
for(i=0 ; i < 100 ; ++i){
printf("*");
}
return 0;
}
- setvbuf
- int setvbuf(FILE *stream, char *buf, int mode , size_t size);
- 功能:可以用在任何打开的流上,改变它的缓冲。参数 mode 必须是下列三个宏之一:
- _IONBF 无缓冲
- _IOLBF 行缓冲
- _IOFBF 完全缓冲
- 返回:成功返回0,失败返回任何值
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(void)
{
char buffer[1024] = " ";
if(setvbuf(stdout,buffer,_IONBF,1024) != 0){
printf("%s",strerror(errno));
}
int i = 0;
for(i=0 ; i < 100 ; ++i){
printf("*");
}
return 0;
}
open函数示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
if (argc < 3){
perror("输入的参数错误!");
exit(1);
}
int fp1 = open(argv[1],O_RDWR | O_CREAT, 0765);
int fp2 = open(argv[2],O_RDWR | O_CREAT, 0765);
if(fp1 < 0 || fp2 < 0){
printf("%s",strerror(errno));
exit(1);
}
printf("fp1:%d,fp2:%d",fp1,fp2);
close(fp1);
close(fp2);
return 0;
}
用系统调用函数read & write 实现 cp
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
if (argc < 3){
perror("输入的参数错误!");
exit(1);
}
int fp1 = open(argv[1],O_RDWR);
int fp2 = open(argv[2],O_RDWR | O_CREAT, 0765);
if(fp1 < 0 || fp2 < 0){
printf("%s",strerror(errno));
exit(1);
}
char buffer[1024] = " ";
while(1){
int fpr = read(fp1,buffer,1024);
if(fpr == 0){
break;
}
write(fp2,buffer,sizeof(buffer));
memset(buffer,0,sizeof(buffer));
}
close(fp1);
close(fp2);
printf("已经将文件%s复制到文件%s中.\n",argv[1],argv[2]);
return 0;
}
运用dup和dup2
- int dup(int oldfd);
int dup2(int oldfd, int newfd);
- oldfd:原先的文件描述符newfd:新的文件描述符
- 功能:文件描述符的复制,由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用newfd参数指定新描述符的数值。如果newfd已经打开,则先将其关闭。如若oldfd等于newfd,则dup2返回newfd,而不关闭它。
- 返回:成功返回新文件描述符, 出错返回-1
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
if (argc < 3){
perror("输入的参数错误!");
exit(1);
}
int fp1 = open(argv[1],O_WRONLY | O_CREAT | O_TRUNC, 0765);
int fp2 = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC, 0765);
if(fp1 < 0 || fp2 < 0){
printf("%s",strerror(errno));
exit(1);
}
int save_fd = dup(1);
dup2(fp1,1);
char *p = "abcdefg";
write(1,p,strlen(p));
dup2(fp2,1);
char *q = "123456";
write(1,q,strlen(q));
dup2(save_fd,1);
char *r = "ok";
write(1,r,strlen(r));
close(fp1);
close(fp2);
puts("");
return 0;
}
fdopen的应用
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int cmp(const void *a,const void *b){
return (*(int *)a > *(int *)b);
}
int main(int argc,char *argv[])
{
if (argc < 3){
perror("输入的参数错误!");
exit(1);
}
int fp1 = open(argv[1],O_RDONLY);
int fp2 = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC, 0765);
if(fp1 < 0 || fp2 < 0){
printf("%s",strerror(errno));
exit(1);
}
FILE* fp = fdopen(fd1,"r");
if(fp == NULL){
printf("%s\n",strerror(errno));
exit(-1);
}
char buffer[1024] = " ";
int *p = NULL;
int len = 0,i = 0;
while(fgets(buffer,1024,fp) == NULL){
p = realloc(p,(length+1)*sizeof(int));
p[len++] = atoi(buffer);
memset(buffer,0,sizeof(buffer));
}
qsort(p,len,sizeof(p[0]),cmp);
memset(buffer,0,sizeof(buffer));
for(i=0 ; i < len ; ++i){
sprintf(buffer,"%d\n",p[i]);
write(fd2,buffer,strlen(buffer));
}
free(p);
p = NULL;
fclose(fp);
fp = NULL;
close(fp1);
close(fp2);
return 0;
}
fcntl函数示例
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(void)
{
int fd = open("1.txt",O_WRONLY | O_CREAT | O_APPEND,0765);
if(fd < 0){
perror("open file fail");
exit(1);
}
int fdF = fcntl(fd,F_GETFL);
fdF &= ~O_APPEND;
fcntl(fd,F_SETFL,fdF);
write(fd,"write ok!\n",strlen("write ok!\n"));
printf("fd :%#o\n",fd);
return 0;
}