Linux 文件
打开/创建文件—编辑文件—保存文件—关闭文件
1.文件的创建与打开
函数原型
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int fd=open(char *pathname, int flags);
int fd=open(char *pathname, int flags, mode_t mode);
int fd=creat(char *pathname, mode_t mode);
返回值 | 描述 |
---|---|
非负整数 fd | 文件描述符 |
-1 | 打开失败 |
参数 | 描述 |
---|---|
pathname | 文件名 |
flag | O_RDONLY 只读打开 |
O_WRONLY 只写打开 | |
O_RDWR 可读可写打开 | |
mode | 访问权限 |
mode: 0600 读 r: 4 写 w: 2 执行 x: 1 |
demo
int fd;
fd=open("./file1",O_RDWR);
if(fd==-1)
printf("open file1 fail!\n");
拓展内容
- open可选参数
以上三个常数中应当只能指定一个;下列常数选项是可选择的:
flags | description |
---|---|
O_CREAT | 若不存在则创建;需同时说明第三个参数,说明新创建的文件权限 |
O_EXCL | 若文件已存在,返回-1;用于判断是否已存在文件 |
O_APPEND | 每次写时都加到文件的后面 |
O_TRUNC | 如果这个文件中本来是有内容的,而且为只读或只写成功打开,清空文件内容并重新写入 |
- creat
返回值 | 描述 |
---|---|
非负整数 fd | 文件描述符 |
-1 | 打开失败 |
filename:绝对路径/相对路径,省略为当前位置
mode 参数宏 | 数字 | 描述 |
---|---|---|
S_IRUSR | 4 | 可读 |
S_IWUSR | 2 | 可写 |
S_IXUSR | 1 | 可执行 |
S_IRWXU | 7 | 可读可写可执行 |
demo
int fd;
fd=creat("./file1",S_IRWXU);
2.文件的读写操作
2.1文件写入
函数原型
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:从buf中写入count字节写到fd文件 (覆盖)
返回值 | 描述 |
---|---|
ssize_t | 成功写入字节数 |
-1 | 写入失败 |
参数 | 描述 |
---|---|
fd | 文件描述符 |
buf | 要写入文件的字符串 |
count | 写入字节数 |
demo
char *buf="hello world!";
int fd,n_write;
fd=open("./file1",O_RDWR);
n_write=write(fd,buf,strlen(buf));
close(fd);
2.2文件读取
函数原型
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从文件中读取count字节到buf字符串中
返回值 | 描述 |
---|---|
非负整数 nread | 实际读到的字节数 |
-1 | 读取失败 |
参数 | 描述 |
---|---|
fd | 文件描述符 |
buf | 读到的数据存储缓冲区 |
count | 读取的字节数 |
注意光标位置:重启文件或移动光标
char *buf="hello world!";
int fd, nwrite, nread;
char readBuf[128];
fd = open("./file1",O_RDWR);
nwrite = write(fd,buf,strlen(buf));
nread = read(fd,readbuf,128);
close(fd);
2.3 光标的移动
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int where);
功能: 将文件光标相对where移动offset个字节,左负右正
参数 | 功能 |
---|---|
fd | 文件描述符 |
offset | 相对where偏移位置,左负右正 |
where | 位置常数 |
SEEK_SET :文件头 | |
SEEK_CUR :当前位置 | |
SEEK_END :文件尾 |
demo: 利用lseek求文件大小
char *buf="hello write";
int fd,sizefile;
fd = open("./file1",O_RDWR);
sizefile = lseek(fd,0,SEEK_END);
printf("the sizeof file=%d \n", sizefile);
close(fd);
main.c:打开+读写
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd,nread,nwrite;
char write_buf[]="yuan jiang long!";
char read_buf[64] = {'\0'};
fd = open("./file1", O_RDWR);
if( fd == -1 )
{
printf("open file1 failed!\n");
fd = open("./file1",O_RDWR | O_CREAT,0600);
if( fd != -1)
printf("feil1 cread success!\n");
}
else
printf("feil1 open success!\n");
nwrite = write(fd, (void *) write_buf, strlen(write_buf));
if (nwrite == -1)
printf("write error!");
else
printf("successful write %d Byte context:%s to file1 \n", nwrite, write_buf);
//通过关闭打开的方式移动光标至文件头
// close(fd);
// fd = open("./file1", O_RDWR);
//移动光标
lseek(fd, 0, SEEK_SET);
nread = read(fd, read_buf, 64);
if(nread == -1)
printf("nread erroe!\n");
else
printf("read %d Byte context: %s from file1\n",nread, read_buf);
close(fd);
return 0;
}
open中可选参数测试程序
//O_CREAT
int fd;
fd=open("./file1",O_RDWR);
if(fd==-1)
{
printf("open file1 fail!\n");
fd=open("./file1",O_RDWR|O_CREAT,0600);
if(fd>0)
printf("file1 creat success!\n");
}
//O_EXCL
int fd=open("./file1",O_RDWR|O_CREAT|O_EXCL,0600);
if(fd==-1)
{
printf("file1 exist!\n");
}
//O_APPEND
char *buf="hello world!";
int fd=open("./file1",O_RDWR|O_APPEND );
int n_write=write(fd,buf,strlen(buf));
if(n_write != -1)
printf("write %d byte to file1!",n_write);
close(fd);
//O_TRUNC
char *buf="hello world!";
int fd=open("./file1",O_RDWR|O_TRUNC);
int n_write=write(fd,buf,strlen(buf));
if(n_write != -1)
printf("write %d byte to file1!",n_write);
close(fd);
3.对比标准C库函数
3.1文件
函数原型
#include <stdio.h>
FILE *fp = fopen(const char *path, const char *mode);
size_t nwrite = fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
size_t nread = fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
int fseek(FILE *stream, long offset, int whence);
int fclose(FILE *fp);
参数解读
参数 | 功能/用处 |
---|---|
path | 文件路径 |
mode | 文件权限,实际对比见下图 |
ptr | 读写缓存,如writeBuf,readBuf |
size | 一次读入/写入的字节数 |
nmemb | 读写次数 |
stream | 文件流fp,相当于fd |
nwrite | 写次数,等于fwrite里的 nmemb |
nread | 实际读到的次数,返回实际的读的次数 |
demo.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp;
int fd,nread,nwrite;
char write_buf[]="yuan jiang long!";
char read_buf[64] = {'\0'};
fp = fopen("./test.txt","w+");
if(fp == NULL)
printf("fopen erroe!\n");
nwrite = fwrite(write_buf, sizeof(char),strlen(write_buf), fp);
fseek(fp, 0, SEEK_SET);
nread = fread(read_buf, sizeof(char), 64, fp);
printf("R: %d %s \n", nread, read_buf);
fclose(fp);
return 0;
}
-
man手册open函数内给出的对比
-
网上找的实际mode解释
-
其他博主整理:总结open与fopen的区别
3.2字符(扩展)
#include <stdio.h>
int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
int feof(FILE *stream);//到文件尾返回1,否则返回0
fpuc demo
int i;
char *str="hello world";
FILE *fp;
int len=strlen(str);
fp=fopen("./test.txt","w+");
for(i=0;i<len;i++)
fputc(*str++,fp);
str++;
fclose(fp);
feof+fgetc
FILE *fp;
char c;
fp=fopen("./test.txt","r");
while(!feof(fp))//nonzero if reach end of file
{
c=fgetc(fp);
printf("%c\n",c);
}
fclose(fp);
4.文件编程小应用
4.1 利用文件编程自定义实现cp命令
编程思路
- 打开源文件
- 读取文件内容到缓冲区
- 打开目标文件
- 将缓冲数据写入目标文件
- 关闭所有文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char ** argv)
{
int fdSrc,fdDes;
int size,nread,nwrite;
char *readBuf = NULL;
if(argc != 3)
{
printf("argc error!\n");
exit(-1);
}
fdSrc = open(argv[1], O_RDONLY );
if(fdSrc == -1)
{
printf("Src File is not exist!");
exit(-1);
}
size = lseek(fdSrc, 0, SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf = (char *)malloc(sizeof(char)*size+8);
nread = read(fdSrc, readBuf, size);
printf("Read %d Byte\n",nread);
fdDes = open(argv[2], O_WRONLY | O_CREAT |O_TRUNC, 0600);
nwrite = write(fdDes, readBuf, strlen(readBuf));
printf("Write %d Byte\n",nwrite);
close(fdSrc);
close(fdDes);
return 0;
}
4.2 修改文件内容
编程思路
- 打开文件并读取数据到缓存
- 在缓存中查找文件需要修改的内容地址 (strstr)
- 修改特定地址的内容
- 将缓存数据重新写入文件
- 关闭文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char ** argv)
{
int fdSrc;
int size,nread,nwrite;
char *readBuf = NULL;
if(argc != 2 )
{
printf("argc error!\n");
exit(-1);
}
fdSrc = open(argv[1], O_RDWR);
if(fdSrc == -1)
{
printf("Src File is not exist!");
exit(-1);
}
size = lseek(fdSrc, 0, SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf = (char *)malloc(sizeof(char)*size+8);
nread = read(fdSrc, readBuf, size);
printf("Read %d Byte\n",nread);
char *p = strstr(readBuf, "LENG=");
p = p + 5;
*p = '9';
lseek(fdSrc, 0, SEEK_SET);
nwrite = write(fdSrc, readBuf, strlen(readBuf));
printf("Write %d Byte\n",nwrite);
close(fdSrc);
return 0;
}
4.2 将其他数据写入文件
- 读写函数原型中的第二个参数为无符号的指针类型,因此可传参int地址,结构体的地址等
- demo:将结构体数组写入文件并读取文件内容
注意: 其他类型数据写入文件后,通过vi查看可能为乱码,但不影响计算机读取
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
struct Test {
int a;
char c;
};
int main(int argc, char ** argv)
{
int fd;
int size,nread,nwrite;
struct Test data1[2] = {{100,'a'},{101,'b'}};
struct Test data2[2];
fd = open("./file1", O_RDWR | O_CREAT, 0600);
if(fd == -1)
{
printf("File is not exist!");
exit(-1);
}
nwrite = write(fd,&data1,sizeof(struct Test) * 2);
if(nwrite == -1)
printf("write error!\n");
lseek(fd, 0, SEEK_SET);
nread = read(fd, &data2,sizeof(struct Test) * 2);
if(nread == -1)
printf("read reeor!\n");
printf("Read: %d %c \n",data2[0].a, data2[0].c);
printf("Read: %d %c \n",data2[1].a, data2[1].c);
close(fd);
return 0;
}