1.文件编程概述
1.我们需要关心的是如何用代码操作文件,实现文件创建,打开,编辑等自动化执行?
windows下如何手动修改文档,比如写一个word文档:
打开/创建文档 -> 编辑文档 -> 保存文档 -> 关闭文档。
Linux下: 通过鼠标进行文档操作和windows一样。(手动完成)
计算机如何帮助我们自动化完成以上操作呢?
操作系统提供了一系列的API,如Linux系统:
打开 | open |
读写 | read/write |
光标移动 | lseek |
关闭 | close |
2.文件打开及创建 open
open函数返回一个文件描述符(一个小的非负整数),后面若对文件进行读取,写入,光标移动等操作,都需要通过open函数的返回值来操作。
参数说明:
Pathname: 要打开的文件名 (含路径,缺省为当前路径)
Flags
O_RDONLY 只读打开
O_WRONLYY 只写打开
O_RDWR 可读可写打开
下面我们来写个demo, (注:可通过man 2 open查询open函数的头文件)
(1)demo1 思路:
1.先创建一个file1的文件。 touch file1
2.编写代码
3.运行代码,(如果存在fie1文件,返回fd 的值(非负整数),否则,返回-1)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
int main()
{
int fd;
fd = open("./file1",O_RDWR);
printf("fd=%d\n",fd);
return 0;
}
(2)demo2 思路:
- 首先没有创建文件file1,打开失败;
- 进入if, 创建file1(O_CREAT),fd为非负整数;
- 文件创建成功;
#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);
if(fd > 0){
printf("file1 successed,fd=%d\n",fd);
}
}
return 0;
}
补充:文件权限
1.可读 r 4
2.可写 w 2
3.执行 x 1
0600中的6 = 4+2, 代表是可读可写。(目的是给文件所有者相应的权限)
3.文件写入操作 write
向缓冲区写一定量的字节 ,然后取出,写入到文件描述符指向的文件中。
参数:
ssize_t write(int fd, const void *buf, size_t count);
demo3
1.创建file1文件(参考demo2)
2.将buf缓冲区的内容写入到fd指向的file1文件中
3.关闭文件(注:打开文件,一定要记得关闭文件)
#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 = "This is a linux!";
// int open(const char *pathname, int flags);
// int open(const char *pathname, int flags, mode_t mode);
fd = open("./file1",O_RDWR);
if(fd == -1)
{
printf("open file1 failed!\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);
if(fd > 0){
printf("file1 successed!\n");
}
}
printf("fd = %d\n",fd);
// ssize_t write(int fd, const void *buf, size_t count);
write(fd,buf,strlen(buf));
close(fd);
return 0;
}
4.文件读取操作 read
将fd所指向的文件读取count个字节的数据存储到buf中。
参数:
ssize_t read(int fd, void *buf, size_t count);
demo4
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
char *buf = "This is a linux!";
char *readbuf; //开辟readbuf,目前是个野指针
fd = open("./file1",O_RDWR);
if(fd == -1)
{
printf("open file1 failed!\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);
if(fd > 0){
printf("file1 successed!\n");
}
}
printf("fd = %d\n",fd);
// n_write 写入的字节数
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);
// 分配内存空间
readbuf = (char *)malloc(sizeof(char)*n_write+1);
//ssize_t read(int fd, void *buf, size_t count);
int n_read = read(fd,readbuf,n_write);
printf("read:%d ,context:%s\n ",n_read,readbuf);
close(fd);
return 0;
}
5.文件光标移动操作 lseek()
offset 偏移值
wherece 位置
SEEK_SET | 文件头 |
SEEK_END | 文件尾 |
SEEK_CUR | 当前光标位置 |
demo5.1
光标移动到开始位置,(修改demo4)
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd;
char *buf = "This is a linux!";
char *readbuf;
// int open(const char *pathname, int flags);
// int open(const char *pathname, int flags, mode_t mode);
fd = open("./file1",O_RDWR);
if(fd == -1)
{
printf("open file1 failed!\n");
fd = open("./file1",O_RDWR|O_CREAT,0600);
if(fd > 0){
printf("file1 successed!\n");
}
}
printf("fd = %d\n",fd);
int n_write = write(fd,buf,strlen(buf));
if(n_write != -1){
printf("write %d byte to file1\n",n_write);
}
//off_t lseek(int fd, off_t offset, int whence);
lseek(fd,0,SEEK_SET); // 文件头偏移值为0
//lseek(fd,-n_write,SEEK_CUR); 当前文件位置往前偏移
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;
}
**demo5.2 **
计算文件的大小,SEEK_END
#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);
// 文件尾的偏移值为0
int file_size = lseek(fd,0,SEEK_END);
printf("file_size:%d\n",file_size);
close(fd);
return 0;
}
6.文件打开创建补充
demo6_1
O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则返回-1.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
int main()
{
int fd;
fd = open("./file1",O_RDWR|O_CREAT|O_EXCL,0600);
if(fd == -1)
{
printf("file1 cunzai!\n");
}
return 0;
}
demo6_2
O_APPEND 每次写时都加入到 文件的尾端。
#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 = "this is a linux!";
fd = open("./file1",O_RDWR|O_APPEND);
printf("open 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);
return 0;
}
demo6_3
O_TRUNC 如果这个文件中,本来有内容,而且为只读或只写成功打开,则将其长度截短为0,写入新的内容。
(这里不做解释,与上述两种写法类似,可以自行理解)
demo6_4
在某个路径下创建一个可读可写可执行文件。
#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 = "this is a linux!";
//int creat(const char *pathname, mode_t mode);
fd = creat("./file2",S_IRWXU); //可读可写可执行
close(fd);
return 0;
}
ls file1 -l 查看文件权限