Linux文件编程
前言
Linux环境
本人用的电脑是windows系统,装的虚拟机是VMware,LInux发行版是ubuntu12.04。
环境搭建教程这里就先不做介绍,如果有需要的可以直接在网站上搜索Linux环境搭建,教程一大堆。
Linux常用命令
命令 | 操作 |
---|---|
CTRL+ALT+T | 拉起命令行 |
xrandr -s | 调整虚拟机的屏幕尺寸 |
CTRL+ALT+加号 | 命令行字体变大 CTRL+ALT+加 |
CTRL+减号 | 命令行字体变小 |
ctrl+L | 清屏 |
ls | 列出当前文件夹下的所有文件 |
pwd | 显示当前文件夹路径 |
mkdir 文件名 | 创建文件夹 |
cd 文件名 | 进入文件夹 |
cd … | 退回上层文件夹 |
ls -a | 显示所有文件(包括隐藏文件和文件夹) |
tab键 | 自动补全 |
mv | 1,mv *.c. 文件名/ 将文件移到对应的文件夹中 |
mv | 2,重命名。 mv a.c b.c |
cp | a.c test.c. 拷贝 |
vi 文件名 | 对文件进行编辑 |
i | 进入输入模式 |
esc | 退出输入模式 |
:wq | 退出vi的命令行模式 |
gcc 文件名 -o 输出文件名 | 编译 |
./输出文件名 | 输出结果 |
ls -l | 查看文件清单(包括时间) |
man 2 函数名 | 查看该函数的解释 |
cd /mnt/hgfs/共享文件夹名. | 进入共享文件夹 |
grep “xxxx” * | 查找所有的xxxx所在的文件 |
以上都是本人在ubuntu系统进行编程时所用到的一些命令,可以进行参考。如有不正确的地方,欢迎指正!
Linux系统提供的API
每一个操作系统都会提供一些专门的API用来对文件进行操作,下面是Linux系统关于文件编程的API总结:
open() 打开文件
int open(const *pathname,int flag);
int open(const *pathname,int flag,mode_t mode);
pathname:要打开的文件名(含路径,缺省为当前路径)
flag:O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
O_APPEND 每次写时都添加到文件的末端
O_CREAT 若文件不存在就创建它,需要同时使用第三个参数mode,用于说明新文件的存取权限
O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则出错
O_TRUNC 打开文件时,如果这个文件中本来是有内容的,而且只为只读或只写成功打开,则将其长度截短为0
mode:一定是在flag当中使用了O_CREAT标志,mode记录待创建的文件的访问权限
write() 向文件中写内容
ssize_t write(int fd,const void *buf,size_t count);
read() 读取文件中的内容
ssize_t read(int fd,void *buf,size_t count);
*buf:存放读取的数据的区域
count:读取多少位数据
lseek() 重新定位光标
off_t lseek(int fd,off_t offset,int whence);
fd:文件标识符
offset:偏移值对whence的偏移值
whence:固定点的位置
SEEK_SET:头
SEEK_CUR:当前位置
SEEK_END:尾
实践:实现linux指令cp
这个实践是我跟着学习的老师设计的一个实践,主要就是运用了上面所说的open(),write(),read(),lseek()这几个函数。后面的部分也会有实践,阅读本文的兄弟姐妹们可以通过实践代码来理解一下API的用法。
程序流程
- 打开源文件
- 读取源文件的内容
- 将读取的内容写入新的文件
- 将源文件和新创建的文件一起关闭
程序源码
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
//如果用linux开发的话,上述的这些头文件可以在命令行用man来查询
int main(int argc,char **argv)
{
int fdSrc; //源文件
int fdDes; //复制之后的文件
char *readbuf = NULL; //存放数据的区域
if(argc != 3) //判断输入的文件是否含有源文件和新的文件
{
printf("copy failed!");
exit(-1);
}
fdSrc = open(argv[1],O_RDWR); //打开源文件
int size = lseek(fdSrc,0,SEEK_END); //通过lseek函数获取文件大小
lseek(fdSrc,0,SEEK_SET); //将光标重新移回文件开头
readbuf = (char *)malloc(sizeof(char)*size+8); //在内存中建立一个存放数据的区域,为了使新建的区域可以刚好满足文件的大小
int n_read = read(fdSrc,readbuf,size); //读取文件,读取的内容会存放到readbuf中
fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600); //打开新建的文件,设置权限
int n_write = write(fdDes,readbuf,strlen(readbuf));//将readbuf中的内容写到新文件中
//关闭源文件和新文件(非常重要!!!)
close(fdSrc);
close(fdDes);
return 0;
}
实践:修改程序的配置文件
程序流程
- 找到需要匹配字符串在搜索文字中的位置(在这里设为a)
- 获取需要查看的字符的位置,通过指针指向从字符位置(a+n)
- 通过指针改变指向位置的字符
- 将修改好的内容重新写入文件
程序需要用到的C函数
char *strstr(const char *havstack,const char *needle); 查找位置
size_t strlen(const char *s); 获取长度
程序源码
#include<stdio.h>
//剩下的头文件通过man命令搜索
int main(int argc,char **argv)
{
int fd;
char *readbuf=NULL;
fd = open(argv[1],O_RDWR);
int size = lseek(fd,0,SEEK_END);
readbuf = (char *)malloc(sizeof(char)*size+8);
int n_read = read(fd,readbuf,size);
char *p = strstr(readbuf,"length="); //查找字符串在文件中的位置
if(p==NULL){
printf("not found!\n");
exit(-1);
}
p = p+strlen("length=");
*p = '5';
int n_write = write(fd,readbuf,strlen(readbuf));
close(fd);
return 0;
}
将结构体写入文件
程序源码
写入一个结构体
#include<stdio.h>
//头文件省略
//定义一个结构体
struct Table
{
int a;
char b;
};
int main()
{
int fd;
struct Table data1={100,"a"};
struct Table data2;
fd = open(".\file1",O_RDWR);
int n_write = write(fd,&data1,sizeof(struct Table));
lseek(fd,0,SEEK_SET);
int n_read = read(fd,&data2,sizeof(struct Table));
printf("Read a is %d\nb is %c",data2.a,data2.b);
return 0;
}
写入多个结构体
#include <stdio.h>
//头文件省略
struct Table{
int a;
char b;
}
int main()
{
struct Table data1[2]={{100,'a'},{101,'b'}};
struct Table data2[2];
int fd;
fd = open("./file1",O_RDWR);
int n_write = write(fd,&data1,sizeof(struct Table)*2);
lseek(fd,9,SEEK_SET);
int n_read = read(fd,&data2,sizeof(struct Table)*2);
printf("Read data1 A is:%d\n,data1 B is %c\n",data1[0].a,data1[0].b);
printf("Read data2 A is:%d\n,data2 B is %c\n",data1[1].a,data1[1].b);
return 0;
}
C标准库提供的API
fopen 打开文件
FILE *fopen(const char *path,const char *node); //常用
path:文件的路径
node:以什么权限打开具体权限:具体权限
fwrite 写内容
size_t fwrite(const void *ptf,size_t size,size_t nmemb,FILE *stream);
ptf:缓冲区
size:写入内容的大小
nmemb:个数
stream:哪个文件
fread 读内容
size_t fread(void *ptr,size_t size,size_t nmemb,File *stream);
各个参数的作用参考fwrite函数的作用
实践
用C标准库API将字符串写入文件
程序代码
#include<stdio.h>
#include<string.h>
int main()
{
File *fd;
char *str = "xxx hao shuai!";
char readbuf[128];
fd = open("./zhang.txt","w+");
fwrite(str,sizeof(char),strlen(str),fd);
//fwrite(str,sizeof(char)*strlen(str),1,fd); 另外一种写法
fseek(fd,0,SEEK_SET);
fread(readbuf,sizeof(char),strlen(str),fd);
//fread(readbuf,sizeof(char)*strlen(str),1,fd);
printf("Read is :%s\n",readbuf);
return 0;
}
用C标准库API将结构体写入文件
程序代码
#include<stdio.h>
struct Table{
int a;
char b;
}
int main()
{
FILE *fp;
struct Table data1={100,'a'};
struct Table data2;
fp = fopen("./file1","w+");
int nwrite = fwrite(&data1,sizeof(struct Table),1,fp);
fseek(fp,0,SEEK_SET);
int nread = fread(&data2,sizeof(struct Table),1,fp);
printf("Read a is :%d,b is %c\n",data2.a,data2.b);
fclose(fp);
return 0;
}
不太重要的
fputc 一个字符一个字符的放进去
int fputc(int c,FILE *stream);
fgetc 一个字符一个字符的取出来
int fgetc(FILE *stream);
feof 是否到达文件的尾巴
int feof(FILE *stream);
没到文件尾巴就为0,到了文件尾巴就为非0
实践:读取文件
#include<stdio.h>
int main()
{
FILE *fp;
char c;
fp = fopen("./xxx.txt","r");
while(!feof(fp))
{
c = fgetc(fp);
printf("%c",c);
}
fclose(fp);
return 0;
}
总结
Linux文件编程没有什么难理解的地方,就是一些API的调用还有一些C语言的知识,所以这篇总结主要还是介绍API的使用方法。上述说法如果有不正确的的地方,欢迎各位大佬指正交流。