一、文件
1、文件编程概述
Linux操作系统提供一系列的API
- 打开 open
- 写 读 write read
- 光标定位 lseek
- 关闭 close
2、文件打开及创建
参数说明
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include <unistd.h>
int main()
{
int fd;//文件描述符,为open()的返回值
fd = open("./file1",O_RDWR); //可读可写的方式打开,字符串本身就是一个指针
if(fd == -1) //如果fd的返回值为-1
{
printf("open file1 failed\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);//如果没有文件file1,则创建一个file1
if(fd > 0)
{
printf("create file1 success!\n");
}
}
close(fd);//关闭fd
return 0;
}
输出结果:
3、文件写入操作编程
ssize_t write(int fd, const void *buf, size_t count);
第一个参数是文件描述符
第二个参数是无类型指针,是一个缓冲区
第三个参数是buf的长度,即写入文件的大小
简单理解就是将buf里面有count个字节的数据写入到fd指向的文件中去
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int fd;//文件描述符,为open()的返回值
char *buf = "I am ok!!!";
fd = open("./file1",O_RDWR);//打开一个file1文件,如果文件不存在,则fd为-1
if(fd == -1)
{
printf("open file1 failed\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);//如果没有文件file1,则创建一个file1
if(fd > 0)
{
printf("create file1 success!\n");
}
}
write(fd,buf,strlen(buf));//把buf中的内容写入file1,
close(fd);//关闭文件
return 0;
}
~
- 注意:
这里用sizeof(buf)会出问题,因为buf是指针,在linux中,指针一般是4个字节(我的是8个字节),会导致写入不完整
4、文件读取操作
ssize_t read(int fd, void *buf, size_t count);
简单理解:从fd指向的文件中读取count个字节到buf中
#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;//文件描述符,为open()的返回值
char *buf = "I am ok!!!";
fd = open("./file1",O_RDWR);
if(fd == -1)
{
printf("open file1 failed\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);//如果没有文件file1,则创建一个file1
if(fd > 0)
{
printf("create file1 success!\n");
}
}
int n_write = write(fd,buf,strlen(buf));//如果写入成功,则返回写入字节个数
if(n_write != -1)
{
printf("write %d byte to file1\n",n_write);
}
close(fd);//关闭fd,然后重新打开文件,为了让光标重新回到开头
fd = open("./file1",O_RDWR);
char *readBuf;//要开辟空间,否则会产生段错误
readBuf = (char *)malloc(sizeof(char)*n_write+1);//开辟readbuf空间
int n_read = read(fd,readBuf,n_write);//如果读取成功,则返回读取字节个数
printf("read %d,context:%s\n",n_read,readBuf);//打印出读取的字节个数和内容
close(fd);
return 0;
}
- 注意:
要让光标从新回到开头,要不然read读取不到内容,这是很土的方式,后面会用到lseek函数操作光标
5、文件光标移动操作
off_t lseek(int fd, off_t offset, int whence);
第一个参数是文件描述符
第二个参数是将文件读写指针相对whence移动offset个字节
第三个参数是光标的位置,SEEK_SET是开头位置,SEEK_CUR是当前位置,SEEK_END是结尾位置
#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;//文件描述符,为open()的返回值
char *buf = "I am ok!!!";
fd = open("./file1",O_RDWR);
if(fd == -1)
{
printf("open file1 failed\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);//如果没有文件file1,则创建一个file1
if(fd > 0)
{
printf("create file1 success!\n");
}
}
int n_write = write(fd,buf,strlen(buf));
if(n_write != -1)
{
printf("write %d byte to file1\n",n_write);
}
/*
close(fd);
fd = open("./file1",O_RDWR);
*/
lseek(fd,0,SEEK_SET);//替换上面两句,重新把光标放到开头,相当于相对于文件开头偏移0个字节
//或者用lseek(fd,-n_write,SEEK_CUR);
char *readBuf;
readBuf = (char *)malloc(sizeof(char)*n_write+1);//开辟空间
int n_read = read(fd,readBuf,n_write);
printf("read %d,context:%s\n",n_read,readBuf);
close(fd);
return 0;
}
- lseek(fd,0,SEEK_END);返回值可以用于计算文件大小
- 用lseek()巧妙计算文件大小代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int fd;//文件描述符,为open()的返回值
char *buf = "I will be successful";
fd = open("./file1",O_RDWR);//打开一个file1文件,如果文件不存在,则fd为-1
int filesize = lseek(fd,0,SEEK_END);
printf("filesize is %d\n",filesize);
close(fd);//关闭文件
return 0;
}
~
输出结果:
6、文件打开创建的补充
- O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则返回值-1
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<stdio.h>
int main()
{
int fd;
fd = open("./file1",O_RDWR|O_CREAT|O_EXCL,0600);//文件已经存在,则返回值-1
if(fd == -1)
{
printf("file1 has hear\n");
}
close(fd);
return 0;
}
输出结果:
- O_APPEND 每次写时都加到文件的尾端
//Test3.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
int main()
{
int fd;
char *buf = "I will be successful\n";
//fd = open("./file1",O_RDWR|O_APPEND,0600);
fd = open("./file1",O_RDWR,0600); //没加 O_APPEND,则会把文件原先内容覆盖
int n_write = write(fd,buf,strlen(buf));
if(n_write != -1)
{
printf("write %d byte to file\n",n_write);
}
close(fd);
return 0;
}
~
输出结果:
文件原先内容:
没加 O_APPEND,则会把文件原先内容位置覆盖:
加 O_APPEND,则会在文件原先内容尾端加上:
- O_TRUNC 属性去打开文件时,如果这个文件中本来是有内容的,而且为只读或只写成功打开,则将其长度截断为0
//Test4.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
int main()
{
int fd;
char *buf = "I will be successful\n";
fd = open("./file1",O_RDWR|O_TRUNC,0600);
int n_write = write(fd,buf,strlen(buf));
if(n_write != -1)
{
printf("write %d byte to file\n",n_write);
}
close(fd);
return 0;
}
~
输出结果:
- 创建creat函数
//Test5.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
int main()
{
int fd;
char *buf = "I will be successful\n";
fd = creat("./file1",S_IRWXU); //可读可写可执行
close(fd);
return 0;
}
输出结果:
文件权限为可读可写可执行
二、往期文章
1、入门Linux系统编程–文件
2、入门Linux系统编程–进程
3、入门Linux系统编程–线程
4、入门Linux系统编程–进程间通信
5、入门Linux系统编程–网络编程