(一)发行版:Ubuntu16.04.7
(二)记录:注意本文中lseek为文件io,其他为目录io(dir)
文件IO:lseek(open,read,write,close)
示例:从第五个字节开始读取文件
#include <stdio.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 copya_fd;
ssize_t read_byte;
off_t offset_position;
char buff[31]={0};
//打开要复制的文件
copya_fd = open("copya.c",O_RDWR);
if(copya_fd == -1)
printf("fail to open copya.c\n");
else
printf("open copya.c successfully:%d\n",copya_fd);
//首地址偏移5个字节
offset_position=lseek(copya_fd,5,SEEK_SET);
printf("start copy index is %d\n",offset_position);
//读取文件内容到buff中
read_byte=read(copya_fd,buff,31);
//关闭文件
close(copya_fd);
//打印读取的字节
printf("read %d bytes from copya.c\n",read_byte);
for(int i=0;i<31;i++)
printf("%c",buff[i]);
printf("\n");
return 0;
}
makefile
lseek:lseek.c
gcc lseek.c -o lseek
clean:
rm -rf lseek
copya.c完整句子
this is a flie which will be copyed.
按这种代码运行,读出的两次结果是一样的,虽然在读的时候指针在一直向后移动,第二次读应该是接着第一次读的末尾位置接着读,但是使用了lsee将指针回到起始位置,所以第二次读又是从开始位置读。
目录IO与文件IO
之前学习的open,read,close,lseek等都是文件IO函数,可以直接操作文件内容。目录IO只能看到子目录或者文件名,不能看到文件的内容。
目录IO:
(1)mkdir函数
#include <stdio.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 feedback;
if(argc!=2)
{
printf("error!");
return -1;
}
feedback=mkdir(argv[1],0666);
if(feedback==-1)
{
printf("fail to make direction.\n");
return -2;
}
return 0;
}
(2) opendir 与 closedir
opendir打开失败则返回NULL,成功则返回一个目录指针
closedir关闭目录传入的是目录指针,即前面opendir返回的目录指针,关闭成功返回0,失败返回-1
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
DIR *dir;
int close_feedback;
if(argc!=2)
{
printf("error!");
return -1;
}
dir=opendir(argv[1]);
if(dir==NULL)
{
printf("fail to open direction.\n");
return -2;
}
close_feedback=closedir(dir);
if(close_feedback == -1)
{
printf("fail to cloase direction.\n");
return -3;
}
return 0;
}
(3)readdir
readdir传入值为一个目录指针,返回值为一个结构体指针,关于返回的结构体指针,我们需关注的为第一个inode号和最后一个文件名。
由于文件系统的存储结构为链式结构,所以读取多个文件时需要以如下方式读取
//链式读取
while(1)
{
//读取目录
drt=readdir(dir);
if(drt!=NULL)
printf("file name : %s ,inode number : %d \n",drt->d_name,drt->d_ino);
else
break;
}
在上述file1文件夹下创建一个sorrow.txt文本,再查看所有信息,其中
第一列为inode号,"."为当前目录的inode号,".."为上一级目录的inode号。
编译运行:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
DIR *dir;
int close_feedback;
struct dirent * drt; //读取目录的结构体指针
if(argc!=2)
{
printf("error!");
return -1;
}
dir=opendir(argv[1]);
if(dir==NULL)
{
printf("fail to open direction.\n");
return -2;
}
//链式读取
while(1)
{
//读取目录
drt=readdir(dir);
if(drt!=NULL)
printf("file name : %s ,inode number : %d \n",drt->d_name,drt->d_ino);
else
break;
}
close_feedback=closedir(dir);
if(close_feedback == -1)
{
printf("fail to close direction.\n");
return -3;
}
return 0;
}
(三)命令:
(4)综合练习:键盘输入被拷贝目录和拷贝目录,打印被拷贝目录中的所有文件名,并且复制被拷贝目录的所有文件到拷贝目录中
比如将如下文件夹中的file1中的hh.c和sorrow.txt拷贝到file2中
运行效果
注意:
这个需要指定拷贝文件个数,并且是从第一个文件开始拷贝,不能超出。 才开始需要输入两个目录,第一个为被拷贝的目录,第二个为拷贝到的目录。如果拷贝到的目录不存在,则会新建一个目录。只能拷贝文件,不能拷贝文件夹。在打开被拷贝目录扫描文件时,将单个文件中的内容读出写到拷贝目录中的拷贝文件中(新建或者打开),传入open参数时,需要将路径加文件名传入,由strcat函数拼接(每次使用完之后需要memset清空),路径为一开始传入的参数,文件名为打开被拷贝目录后读被拷贝目录时得到的,copyed_drt->d_name。复制完单个文件后需要关闭,等到下一个文件读取时再打开或新建文件重复操作。重复多少次由输入的copy_filenumber决定(第一个跳过,第一个为上一级 ..)。只要使用到字符数组,才开始一定要初始化为{0}否则会有乱码。目前我设置的读取文件内容的字符数组只有buffsize=32这么大(buff[32]),如果需要读取比较多的内容需要将这两个改大。
/*
*输入的第一个是被拷贝目录
*输入的第二个是拷贝目录
*接着输入要拷贝的文件个数
*需要将被拷贝目录下的所有文件名打印出来
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
int main(int argc,char *argv[])
{
DIR *copyed_dir;
struct dirent * copyed_drt;
int copyed_fd;
int copy_fd;
char temp_buff1[32]={0}; //文件路径
char temp_buff2[32]={0};
int copy_filenumber; //复制文件的个数
int index; //用以错开 .. .
/*
*修改buffsize可以改变每个文件读取的字符数
*/
ssize_t read_bytes; //读取文件中的数据个数
char buff[32]={0}; //读取的字符
size_t buffsize=32;
if(argc!=3)
{
printf("error input.\n");
return -1;
}
//1.打开被拷贝目录和拷贝目录
copyed_dir=opendir(argv[1]);
mkdir(argv[2],0666);
printf("please enter the number of files you want to copy:\n");
scanf("%d\n",©_filenumber);
//2.打印被拷贝目录中的所有文件名
while(1)
{
copyed_drt=readdir(copyed_dir);
if(copyed_drt!=NULL)
{
printf("%s\n",copyed_drt->d_name);
//3.复制被拷贝目录下的文件到拷贝目录下
if((index>0) && (index < (copy_filenumber+1)))
{
strcat(temp_buff1,argv[1]);
strcat(temp_buff1,"/");
strcat(temp_buff1,copyed_drt->d_name);
strcat(temp_buff2,argv[2]);
strcat(temp_buff2,"/");
strcat(temp_buff2,copyed_drt->d_name);
copyed_fd=open(temp_buff1,O_RDWR);
copy_fd=open(temp_buff2,O_RDWR|O_CREAT,0666); //创建或者打开
if((read_bytes=read(copyed_fd,buff,buffsize))!=0)
write(copy_fd,buff,buffsize);
else
printf("read error.\n");
close(copyed_fd);
close(copy_fd);
memset(temp_buff1,0,sizeof(temp_buff1));
memset(temp_buff2,0,sizeof(temp_buff2));
}
index++;
}
else
break;
}
closedir(copyed_dir);
return 0;
}