刚到这个论坛,感觉学术性很强,好多大牛啊(膜拜),同时我也在不懈的努力学习着,最近因运维需要,写了一款Unix上的工具。我把以前学习Unix的过程经历和大家一起分享,让更多人一起学习,自己也是一次复习吧。授人以鱼不如授人以渔
Unix是一款操作系统,怎么产生的以及背景什么的这里就不介绍了,百度一大篇,切入正题。
编程语言用的C语言.
在开发软件中肯定会用到文件IO(文件读写),如 软件的配置文件 、保存运行数据等、把软件运行过程中产生的数据持久保存到磁盘的操作就称为 文件IO
这里首先说明一个概念 :
文件描述符 int类型的整数
文件描述符是Unix内核记录与之相关连文件当前状态的一个标志,每个进程中都有一张文件描述符表,这张表里记录着每个文件描述符对应文件的状态,如
当前偏移、文件属性、权限等信息。
举个例子吧,银行卡对应户主在银行里存款的状态(当前余额、是否冻结、附属卡等),通过银行卡可以存取银行对应的数据信息,当打开一个文件Unix内核会返回一个文件描述符给程序,而程序则通过这个文件、
描述符操作对应的文件。
Unix 最常用到的文件IO函数
int open( const char *pathname, int flags);
打开一个文件
pathname
待打开的文件路径
flags 标示
有以下常用标识
O_RDONLY
以只读方式打开文件
O_WRONLY
以只写方式打开文件
O_RDWR
以可读写方式打开文件。上述三种旗标是互斥的,也就是不可同时使用,但可与下列的旗标利用OR(|)运算符组合。
O_CREAT
若欲打开的文件不存在则自动建立该文件。
O_SYNC
以同步的方式打开文件。
O_APPEND
当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。
ssize_t read(int fd, void *buf, size_t count);
读取文件
fd
文件描述符
buff
存放读取文件数据的数组
count
读取多少
ssize_t write(int fd, const void *buf, size_t count);
写入文件
fd
文件描述符
buff
待写入文件的数据
count
写入多少
int close(int fd);
关闭文件
fd 文件描述符
int sync(void);
刷新缓冲区,将缓冲区中的数据写入到磁盘
off_t lseek(int fildes, off_t offset, int whence);
设置文件当前偏移量
fildes
文件描述符
offset
要移动的偏移量
whence
移动标志
有以下定义
SEEK_SET
从文件起点为基准移动到offset位置。
SEEK_CUR
以当前位置加上offset偏移量(偏移量可以是负数)。
int dup(int oldfd);
复制一个文件描述符,但都指向同一个文件(意思是对一个文件的读写,会影响到另一个文件描述符)
oldfd 待复制的文件描述符#include <stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
int main(void)
{
int fd=-1; //文件描述符
char buff[1024]; //字节数组
int rlen; //读写长度记录
//调用Linux api open创建文件
fd=-1;
fd= open("/root/cpp/io_linux/file1.dat",O_RDWR|O_CREAT); //以读写方式创建一个文件
if(fd<0) //如果返回的文件描述符小于0则说明失败了
{
printf("create file faild...\n");
}
else
{
printf("create file success...\n");
}
close(fd); //关闭打开的文件
//写文件
fd=open("/root/cpp/io_linux/file1.dat",O_WRONLY|O_TRUNC); //以读写方式打开一个文件并将文件内容截断为0(这里可以理解成清空原有数据从新写入)
printf(">>>");
fgets(buff,1024,stdin);//从标准输入读入数据
buff[strlen(buff)-1]='\0'; //fgets 结束符是\n,要替换成\0
write(fd,buff,strlen(buff));//将标准输入的数据写入文件描述符对应的文件,文件描述符对应的偏移量等于当前偏移量+写入数据的长度
close(fd);//关闭打开的文件
//读文件
fd=open("/root/cpp/io_linux/file1.dat",O_RDONLY); //以读写方式打开一个文件
lseek(fd,1,SEEK_SET); //将文件描述符偏移量移动到1位置
int rlen=(int)read(fd,buff,1024); //从文件描述符当前位置读取1024字节数据,并存到buff字节数组中(注意这里指定读取1024字节,实际如果文件没有这么长的数据)
//则以实际读取为准,它的返回值为实际读取的字节长度
b
uff[rlen]=’\0’;
printf(“read len: %d content:%s\n”,rlen,buff);
//文件共享dup 复制当前文件描述符(读写位置 权限等)
fd=open("/root/cpp/io_linux/file1.dat",O_RDONLY);//以读写方式打开一个文件
int nfd=dup(fd);//复制fd文件描述符
rlen=read(fd,buff,5);//读取fd文件5个字节数据
buff[5]='\0';
printf("read1: %s\n",buff);
rlen=read(nfd,buff,3); //读取复制后的文件描述符3个字节数据
buff[rlen]='\0';
printf("read2: %s\n",buff);
exit(0);
}