1.open 打开文件
在LINUX环境下使用命令符查询 (man 2 open)
#include <sys/types.h>//使用open需包含的头文件
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);//返回一个文件描述符
int open(const char *pathname, int flags, mode_t mode);
/*
const char *pathname(存放文件的地址)
mode_t mode(通常定义为0600(存取许可为可读可写))
int flags 的类型有:
O_RDONLY //只读打开
O_WRONLY //只写打开
O_RDWR // 可读可写打开
可搭配
O_CREAT //若文件不存在则创建它,使用此选项时通常需搭配第三个参数(mode),说明新文件的存取许可,通常定义为(0600)
O_EXCL //如果同时指定了O_CREAT ,而文件已经存在,则出错
O_APPEND //每次写时都加到文件的尾端
O_TRUNC //O_TRUNC属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截短为0;(删除原文件中的所有内容)
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("./file",O_RDWR);
printf("fd = %d\n",fd);
if(fd == -1){
printf("open fail!\n");
fd = open("./file",O_RDWR|O_CREAT,0600);//若打开失败,则创建文件
if(fd > 0){
printf("create succes!\n");
}
}
if(fd > 0){
printf("open succes!\n");
}
return 0;
}
2.read 读文件
在LINUX环境下使用命令符查询 (man 2 read)
#include <unistd.h> //使用read需包含的头文件
ssize_t read(int fd, void *buf, size_t count);//读取成功返回读取数,失败返回-1
/*
int fd(文件描述符,打开文件的返回值)
void *buf(存放读的内容,地址,指针)
size_t count(可读的大小)
*/
#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 = "LiXiang123456";
fd = open("./file",O_RDWR);
printf("fd = %d\n",fd);
if(fd == -1){
printf("open fail!\n");
fd = open("./file",O_RDWR|O_CREAT,0600);
if(fd > 0){
printf("create succes!\n");
}
}
if(fd > 0){
printf("open succes!\n");
}
int n_write = write(fd,buf,strlen(buf));
if(n_write != -1){
printf("write %d to file\n",n_write);
}
// close(fd);
// fd = open("./file",O_RDWR);
char *readBuf;
readBuf = (char *)malloc(sizeof(char)*n_write);
lseek(fd,0,SEEK_SET);
int n_read = read(fd,readBuf,n_write);
if(n_read != -1){
printf("read %d context:%s\n",n_read,readBuf);
}
close(fd);
return 0;
}
3.write 写文件
在LINUX环境下使用命令符查询 (man 2 write)
#include <unistd.h> //使用write需包含的头文件
ssize_t write(int fd, const void *buf, size_t count);//写入成功,返回写入个数,失败返回-1
/*
int fd(打开文件的返回值)
const void *buf(写的内容,地址(是指针就行))
size_t count(写多少,空间的大小)
*/
#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 = "LiXiang123456";
fd = open("./file",O_RDWR);
printf("fd = %d\n",fd);
if(fd == -1){
printf("open fail!\n");
fd = open("./file",O_RDWR|O_CREAT,0600);
if(fd > 0){
printf("create succes!\n");
}
}
if(fd > 0){
printf("open succes!\n");
}
write(fd,buf,strlen(buf));//这里的大小使用strlen读字符串的大小,不用sizeof,sizeof读的是指针的大小8个字节。
close(fd);//关闭文件
return 0;
}
4.lseek 移动光标
在LINUX环境下使用命令符查询 (man 2 lseek)
#include <sys/types.h> //使用lseek需包含的头文件
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence); //返回光标移动的个数
int size = lseek(fd,0,SEEK_END);//实现文件大小的读取,记得复位。
/*
int fd(打开文件的返回值)
off_t offset(偏移值(0))
int whence(把光标移向某个位置)
可选
SEEK_SET 开头
SEEK_CUR 当前
SEEK_END 尾
*/
5.实现cp操作
#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 fd1;
int fd2;
char *fdBuf=NULL;
fd1 = open(argv[1],O_RDWR);//用可读可写的方式,打开对象1,并返回给文件描述符。
if(fd1 < 0){
printf("打开失败!\n");
exit(-1);
}
int size = lseek(fd1,0,SEEK_END);//返回光标从头到尾的偏移值,
lseek(fd1,0,SEEK_SET);//把光标移到头
fdBuf=(char *)malloc(sizeof(char)*size+8);//开辟fdBuf的空间大小,+8是为了避免空间不够
int n_read = read(fd1,fdBuf,size);//把fd1读到fdBuf中,读size大小的数据
if(n_read < 0){
printf("读取内容失败!\n");
exit(-1);
}
fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
/*用可读可写的方式,打开对象2,如果对象2不存在,则创建对象2(O_CREAT)。
(O_TRUNC)是为了若对象2存在内容时,清除对象2中的数据,避免出现复制的内容小于对象2的内容,指出现不能完全覆盖的现象。
(0600)定义存取许可*/
int n_write = write(fd2,fdBuf,strlen(fdBuf));//把fdBuf写到fd2中,写fdBuf大小的数据
if(n_write < 0){
printf("写入内容失败!\n");
exit(-1);
}
close(fd1);//关闭文件,防止文件损坏
close(fd2);
return 0;
}
6.strstr 对比(查找)
#include <string.h> //需包含的头文件
char *strstr(const char *haystack, const char *needle);//地址(文件路径);具体差某一项时需加" ",例:"LIXIANG="。此时光标在L位置。
7.实现对文件某个内容的修改(修改配置文件)
#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 fd1;
char *fdBuf=NULL;
fd1 = open(argv[1],O_RDWR);
if(fd1 < 0){
printf("打开失败!\n");
exit(-1);
}
int size = lseek(fd1,0,SEEK_END);//文件大小
lseek(fd1,0,SEEK_SET);//复位
fdBuf=(char *)malloc(sizeof(char)*size+8);
int n_read = read(fd1,fdBuf,size);
if(n_read < 0){
printf("读取内容失败!\n");
exit(-1);
}
printf("read success %d",n_read);
char *p = strstr(fdBuf,"LENG=");//此时光标在L
if(p == NULL){
printf("查找失败!\n");
exit(-1);
}
p = p + strlen("LENG=");//把光标移到=后的位置
*p = '5';//把=后一位的数改为5;注意是字符的格式
lseek(fd1,0,SEEK_SET);//把光标移到开头位置,为写入做准备工作
int n_write = write(fd1,fdBuf,strlen(fdBuf));
if(n_write < 0){
printf("写入内容失败!\n");
exit(-1);
}
close(fd1);
return 0;
}
8.将一个结构体写入文件中
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
struct Test
{
int a;
char c;
};
int main(int argc,char **argv)
{
int fd1;
struct Test data[2] = {{100,'a'},{101,'b'}};
struct Test data2[2];
fd1 = open("./file",O_RDWR);
if(fd1 < 0){
printf("打开失败!\n");
exit(-1);
}
int n_write = write(fd1,&data,sizeof(struct Test)*2);//将data中的内容写到(fd1)file,写两个结构体大小的数据
if(n_write < 0){
printf("写入内容失败!\n");
exit(-1);
}
lseek(fd1,0,SEEK_SET);//把光标移到开头位置,为读做准备工作
read(fd1,&data2,sizeof(struct Test)*2);//将file(fd1)中的内容读到data2,读两个结构体大小的数据
printf("read %d %c\n",data2[0].a,data2[0].c);
printf("read %d %c\n",data2[1].a,data2[1].c);
close(fd1);
return 0;
}
9.create 创建文件
#include <sys/types.h> //需包含的头文件
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);
/*
const char *pathname(路径加文件名,例"./file")
mode_t mode(创建模式)
可选
S_IRUSR 可读(4)
S_IWUSR 可写(2)
S_IXUSR 可执行(1)
S_IRWXU 可读可写可执行(7)
*/
10.LINUX系统中默认文件描述符(fd)有:0(标准输入)、1(标准输出)、2(标准错误)。
11.静态文件与动态文件的区别
静态文件:在硬盘中保存的文件,例在桌面上的文件。
动态文件:open静态文件之后,会在LINUX内核产生一个结构体(fd,信息节点,buf=(内容,close)),close(fd);将动态文件写入到静态文件。所以当打开文件后记得关闭文件。将静态文件从块设备中读取到内核中特定地址管理存放。
为什么不直接使用块设备,因为块设备不灵活,例如说每块有100个字节,那么小于100个字节的数据则会无法读取。