#Linux系统编程(lseek函数与目录IO函数mkdir,opendir,closedir,readdir及综合练习)

(一)发行版: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",&copy_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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值