写一篇关于Linux系统文件编程的文章,将所学的知识重新回顾一遍,并记录下来 .就如同window界面创建文档一样,在Linux操作系统中也分为这四个步骤:打开/创建文档->编辑文档->保存文档->关闭文档。在Linux操作系统中提供了一系列的API供我们使用。其中,打开:open、读写:write/read、光标定位:lseek、关闭:close。
1.open
查找open,这里给我们提供了3个函数,我们先用第一种。这里的flags有三种:O_RDONLY只读打开、O_WRONLY只写打开、O_RDWR可读可写打开。文件描述符成功打开文件则返回3,失败则返回-1.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;//文件描述符
fd = open("./file1",O_RDWR);//表示文件的路径和状态
printf("%d\n",fd);
return 0;
}
当该路径无file1这个文件时,就需要我们创建一个,那么我们就用到第二种。当然创建一个文件是需要权限的,mode_mode就是我们要的权限,这里我们用0600,表示可读可写。这里的权限有三:可读 :4、可写:2、可执行:1。用r、w、x表示。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fd;//file descriptor
// int open(const char *pathname, int flags);
fd = open("./file1",O_RDWR);
if(fd == -1)
{
printf("flie1,falied\n");
// int open(const char *pathname, int flags, mode_t mode);
fd = open("./file1",O_RDWR|O_CREAT,0600);
}
if(fd > 0)
{
printf("create file1\n");
}
printf("open success : fd = %d\n",fd);
2.write
接下来,我们要将数据写入到文件里面那么我们就要用到write。
这是write的函数,write(int fd,const void *buf,size_t count),从左到右,依次是:文件描述符,写入该文件的数据、数据的长度。 我们将char *buf写入文件中。write函数返回的是数据的长度。最后关闭文件close(fd)。
int fd;//file descriptor
char *buf = "yi shu wei ban";
// int open(const char *pathname, int flags);
fd = open("./file1",O_RDWR);
if(fd == -1)
{
printf("flie1,falied\n");
// int open(const char *pathname, int flags, mode_t mode);
fd = open("./file1",O_RDWR|O_CREAT,0600);
}
if(fd > 0)
{
printf("create file1\n");
}
printf("open success : fd = %d\n",fd);
// ssize_t write(int fd, const void *buf, size_t count);
int n_write = write(fd,buf,strlen(buf));
if(n_write != -1)
{
printf("write %d byte to file\n",n_write);
}
close(fd);
3.read
和write的用法差不多,不过一个读一个写。
int n_write = write(fd,buf,strlen(buf));
if(n_write != -1)
{
printf("write %d byte to file\n",n_write);
}
// close(fd);
// fd = open("./file1",O_RDWR);
// off_t lseek(int fd, off_t offset, int whence);
int file_size = lseek(fd,0,SEEK_END);
char *readBuf;
readBuf =(char *)malloc(sizeof(char)*n_write + 1);
// ssize_t read(int fd, void *buf, size_t count);
int n_read = read(fd,readBuf,n_write);
4.seek光标
当我们在进行读写指令操作时,通常存在一个问题,就是读完文件后我们再写文件或者写完文件后我们再读文件都会读不到或写不到。就是因为我们的光标到达尾巴。这需要我们重新把光标调回去。这样,才可以继续读或写。lseek(int fd,off_t offset,int whence),文件描述符、偏移值、光标位置(如下图2:开头、当前位置、尾巴),将文件读写指针相对whence移动offset个字节。其返回值是off_t offset相对开头的距离。
5.open的补充
O_EXCL(如果同时指定了OCREAT,而文件存在,则出错)、O_TRUNC(打开文件时,如文件里面有内容,将其清理)、O_APPEND(每次写时都加在尾端).
int creat(const char *pathname, mode_t mode).本质上和0600是一样的。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
# include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fd;
char *buf = "yi shu wei ban";
// fd = open("./file1",O_RDWR|O_CREAT|O_EXCL,0600);
// fd = open("./file1",O_RDWR|O_TRUNC,0600);
// fd = open("./file1",O_RDWR|O_APPEND,0600);
// int creat(const char *pathname, mode_t mode);
creat("/home/CLC/file2",S_IRWXU);
write(fd,buf,strlen(buf));
return 0;
}
6.实现Linuxcp命令的代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char **argv)//三个参数。指向指针数组的指针,原型:char *argv[].
{
char *readBuf=NULL;
if(argc != 3)
{
printf("params erroe\n");
exit(-1);
}
int fd_src = open(argv[1],O_RDWR);//打开源文件
int size = lseek(fd_src,0,SEEK_END);//计算src文件中数据长度,这里把光标调到末尾。
lseek(fd_src,0,SEEK_SET);//将光标重新调到开头
readBuf = (char *)malloc(size*sizeof(char)+16);//动态开辟空间
read(fd_src,readBuf,size);//读取数据,存在readBuf.
int fd_des = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);//打开目标文件,不存在则创建,存在则清空。
write(fd_des,readBuf,strlen(readBuf));//将readBuf中的数据写入。
close(fd_src);//关闭源文件
close(fd_des);//关闭目标文件
return 0;
}
7.修改程序的配置文件
源文件如上图,修改score=9这个9的数值。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
char *readBuf=NULL;
char *p=NULL;
if(argc != 2)
{
printf("params erroe\n");
exit(-1);
}
int fd_src = open(argv[1],O_RDWR);//打开需要修改的文件
int size = lseek(fd_src,0,SEEK_END);//计算长度
lseek(fd_src,0,SEEK_SET);//调整光标
readBuf = (char *)malloc(size*sizeof(char)+16);//开辟空间
read(fd_src,readBuf,size);//读取数据
// char *strstr(const char *haystack, const char *needle);
p = strstr(readBuf,"SCORE=");//在readBuf中查找对应的字符串的位置
if(p == NULL)
{
printf("error\n");
exit(-1);
}
p = p+strlen("SCORE=");//移动到要修改的数据的位置
*p = '7';//修改数据
lseek(fd_src,0,SEEK_SET);//调整光标
write(fd_src,readBuf,strlen(readBuf));//将修改的数据写入
close(fd_src);//关闭文件
return 0;
}
8.写一个结构体到文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct test
{
int a;
char c;
};
int main()
{
int fd;
struct test data[2]={{5,'c'},{6,'d'}};
struct test data1[2];
fd = open("./file1",O_RDWR);
// ssize_t write(int fd, const void *buf, size_t count);
write(fd,&data,sizeof(struct test)*2);
lseek(fd,0,SEEK_SET);
// ssize_t read(int fd, void *buf, size_t count);
read(fd,&data1,sizeof(struct test)*2);
printf("data1 is :%d and %c\n",data1[0].a,data1[0].c);
printf("data1 is :%d and %c\n",data1[1].a,data1[1].c);
close(fd);
return 0;
}
9.fopen、fwrite、fread
fopen和open函数的区别:
1.来源:open是UNIX系统调用函数(包括LINUX等),返回的是文件描述符,它是文件在文件描述符里的索引。fopen:是ANSIC标准的C语言库函数,在不同的系统中应该调用不同的内核api。返回的是一个指向文件结构的指针。2.移植性:fopen是标准C库函数,因此具有良好的移植性;而open是UNIX系统调用,移植性有限。如window下相似的功能使用API函数CreateFile. 3.适用范围:open返回文件描述符,而文件描述符是UNIX系统下一个重要概念,UNIX下的一切设备都是以文件的形式操作。如网络套接字、硬件设备等。当然包括操作普通正规文件。fopen操纵普通正规文件。4.文件IO层次:如果从文件的IO的角度来看,前者属于低级IO函数,后者属于高级IO函数。低级和高级的简单区分标准是:谁离系统内核更近。低级文件IO运行在内核态,高级文件运行在用户态。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fd;
char *str="yi shu wei ban";
char *readBuf=NULL;
// FILE *fopen(const char *path, const char *mode);
fd = fopen("/home/CLC/study/file2","w+");
// size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
fwrite(str,sizeof(char),strlen(str),fd);
int size = fseek(fd,0,SEEK_END);
readBuf = (char *)malloc(sizeof(char)*size+16);
fseek(fd,0,SEEK_SET);
// size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
fread(readBuf,sizeof(char),strlen(str),fd);
printf("read is :%s\n",readBuf);
fclose(fd);
}
10.标准C库写结构体
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct test
{
int a;
char c;
};
int main()
{
FILE *fp;
struct test data[2]={{5,'c'},{6,'d'}};
struct test data1[2];
fp = fopen("./file3","w+");
// size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
fwrite(&data,sizeof(struct test),2,fp);//第一种形式
fwrite(&data,sizeof(struct test)*2,1,fp);//第二种形式
fseek(fp,0,SEEK_SET);
// size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
fread(&data1,sizeof(struct test),2,fp);
printf("data1 is :%d and %c\n",data1[0].a,data1[0].c);
printf("data1 is :%d and %c\n",data1[1].a,data1[1].c);
fclose(fp);
return 0;
}
11.fgetc(输出)、fputc(输入)、feof (判断是否到达文件的尾巴,到达为1)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char *str = "yi shu wei ban";
int i;
int size;
size = strlen(str);
fp = fopen("./file4","w+");
// int fputc(int c, FILE *stream);
for(i = 0;i < size;i++)
{
fputc(*str,fp);
str++;
}
fclose(fp);
return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char c;
fp = fopen("./file4","r");
while(!feof(fp))
{
c = fgetc(fp);
printf("%c",c);
}
fclose(fp);
return 0;
}