如何用代码操作文件,实现文件的创建,打开,编辑等自动化执行?
操作系统提供了一系列的API。
如Linux系统:
打开:open
读写:write/read
光标定位:lseek
关闭:close
打开/创建文件:
c
SYNOPSIS
//头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);//指针指向文件路径,int 权限
int open(const char *pathname, int flags, mode_t mode);//
/*pathname:要打开的文件名(含路径,缺省为当前路径)
Flags:
O_RDONLY只读打开 O_WRONLY只写打开 O_RDWR 可读可写打开
(文件不存在,返回值为-1)
O_CREAT:若文件不存在则创建它。使用此选项时,需要同时说明第三个参数mode,用其说明该文件的存取许可权限
O_EXCL:如果同时指定了O_CREAT,而文件已经存在,则出错:打开文件失败或者返回值为-1。
O_APPEND:每次写时都加到文件尾端,j如不加O_APPEND则覆盖之前的内容。
O_TRUNC:属性去打开文件时,如果文件本来是有内容的,而且为只读或只写成功打开,则其长度截短为0,把之前内容全部删除,重新写入.
Mode:一定是在flagse中使用了O_CREAT标准,mode记录待创建的文件的访问权限
*/
int creat(const char *pathname, mode_t mode);
DESCRIPTION//描述
Given a pathname for a file, open() returns a file descriptor,a small,nonnegative integer for use in subsequent system calls (read(2),write(2),lseek(2),fcntl(2),etc.),The file descriptor returned by a successful call will be the lowestnumbered file descriptor not currently open for the process.
/*给定一个文件的路径名,open() 返回一个文件描述符,一个小的非负整数,用于后续的系统调用(read(2)、write(2)、lseek(2)、fcntl(2)等),成功调用返回的文件描述符将是当前未为进程打开的最低编号文件描述符。
*/
例:
c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("./file1",O_RDWR);
if(fd == -1){
printf("open file1 failed\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);//0600可读写权限(4+2)
/*权限: 宏表示
可读:r 4 S_IRUSR
可写:w 2 S_IWUSR
执行:x 1 S_IXUSR
可读,写,执行 7 S_IRWXU
*/
if(fd > 0){
printf("create file1 success!\n");
}
}
return 0;
}
文件的写入:
c
#include <unistd.h>
ssize_t write(int fd,const void *buf,size_t count);
//fd文件描述符,缓冲区指针,大小(count字节)
c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int fd;
char *buf = "laowang hao bang!";
fd = open("./file1",O_RDWR);//打开文件file1
if(fd == -1){
printf("open file1 failed\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);//0600可读写权限(4+2)
/*权限:
可读:r 4
可写:w 2
执行:x 1
*/
if(fd > 0){
printf("create file1 success!\n");
}
}
printf("open success:fd = %f\n",fd);
write(fd,buf,sizeof(buf));//sizeof分配8个字节给buf
write(fd,buf,strlen(buf));//全部显示
close(fd);
return 0;
}
文件读取:
c
#include <unistd.h>
ssize_t read (int fd,const void *buf,size_t count);
//fd文件描述符,缓冲区指针,大小(count字节)
> 光标重新定位:
#include <sys/types.h>
#include <unistd.h>
off_t lseek (int fd,off_t offset,int whence);
fd文件描述符,偏移值,位置
(seek_set,指向文件的头)
(seek_end,指向文件的尾)
(seek_cur,指向文件光标当前位置)
c
#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 = "laowang hao bang!";
fd = open("./file1",O_RDWR);//打开文件file1
if(fd == -1){
printf("open file1 failed\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);//0600可读写权限(4+2)
/*权限:
可读:r 4
可写:w 2
执行:x 1
*/
if(fd > 0){
printf("create file1 success!\n");
}
}
printf("open success:fd = %f\n",fd);
int n_write = write(fd,buf,sizeof(buf));//sizeof分配8个字节给buf
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);//重新打开文件file1
char *readBuf;
readBuf = (char *)malloc(sizeof(char)*n_write + 1);//char的大小*文件大小+1
lseek(fd,0,SEEK_SET);//光标重新定位
int n_read = read(fd,readBuf,n_write);
printf("read %d ,context:%s\n",n_read,readBuf);
close(fd);
return 0;
}
文件描述符 = open(文件,--------)是一个非负整数
Linux系统中有默认的文件描述符:
0 标准输入 STDIN_FILENO
1 标准输出 STDOUT_FILENO
2 标准错误 STDERR_FILENO
文件有静态文件和动态文件
动态文件 = open 静态文件 后在Linux内核产生一个结构体
fd
信息节点
buf(内容)相当于内存
用close之后存入磁盘静态文件
练习1:实现Linux cp命令的代码
参数argc:
参数0 参数1 参数2
cp 源文件(src) 目标文件(des)
argv[0] argv[1] argv[2]
思路:
1.打开源文件
2.读源文件到buf
3.打开/创建目标文件
4.将buf写入到目标文件
5.close两个文件
编译:gcc 文件 -o mycp
./mycp 源文件 目标文件
c
#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)
{
int fdSrc,fdDes;
char readBuf[1024] = {0};
if(argc != 3){
printf("pararm error\n");
exit(-1);
}
fdSrc = open(argv[1],O_RDWR);//打开文件
int n_read = read(fdSrc,readBuf,1024);
fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
int n_write =write(fdDes,readBuf,strlen(readBuf));
close(fdSrc);
close(fdDes);
return 0;
}
练习2:实现配置文件的修改
man strstr//查询strstr用法
如:
读取出来为:
SPEED = 3
LENG = 3
SCORE = 9
LEVEL = 5
修改为:
SPEED = 5
LENG = 100
SCORE = 90
LEVEL = 95
思路:1.找到修改位置的行
2.在该行中找到需要修改的位置
3.修改该位置
c
#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)
{
int fdSrc,fdDes;
char *readBuf = NULL;
if(argc != 2){
printf("pararm error\n");
exit(-1);
}
fdSrc = open(argv[1],O_RDWR);//打开文件
int size = lseek(fdSrc,0,SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf = (char *)malloc(sizeof(char)*size + 8);
int n_read = read(fdSrc,readBuf,1024);
char *p = strstr(readBuf,"LENG=");
if(p==NULL){
printf("not founf\n");
exit(-1);
}
p = p+strlen("LENG=");
*p = "100";
lseek(fdSrc,0,SEEK_SET);//移动光标
int n_write =write(fdSrc,readBuf,strlen(readBuf));
close(fdSrc);
return 0;
}