
最简单的就是:打开一个文件(open函数),把要写入的信息、数据通过write函数写入文件中,然后再用close函数关闭文件。这种是适时性的,一般我们会有缓冲区(通过建立一个临时文件或备份文件),即写入文件中的信息并没有直接写入到原文件,而是写入到缓冲区中,在应用程序中,如果我们确定要写入原文件,可以通过一个命令来把缓冲区中的内容再真正写入(可以用备份文件来替换原文件)到原文件中。
不管是哪种 *** 作系统,要实现文件拷贝,必须陷入内核,从磁盘读取文件内容,然后存储到另一个文件。实现文件拷贝最通常的做法是:读取文件用系统调用read()函数,读取到一定长度的连续的用户层缓冲区,然后使用write()函数将缓冲区内容写入文件。也可以用标准库函数fread()和fwrite(),但这两个函数最终还是通过系统调用read()和write()实现拷贝的,因此可以归为一类(不过效率肯定没有直接进行系统调用的高)。一个更高级的做法是使用虚拟存储映射技术进行,这种方法将源文件以共享方式映射到虚拟存储器中,目的文件也以共享方式映射到虚拟地址空间中,然后使用memcpy高效地将源文件内容复制到目的文件中。点击(此处)折叠或打开#include#include#include#include#include#include#include#include#include#include#defineerror(fmt,args)\printf(fmt,##args)\printf(":%s\n",strerror(errno))inlineintcp_rw(intsrcfd,intdstfd,char*buf,intlen)inlineintcp_map(intsrcfd,intdstfd,size_tlen)intmain(intargc,char**argv){charbuf[8192]intsrcfd,dstfdclock_tstart,endstructtmsstm,ntmstructstatfilestatinttckcharcmdline[30]if(argc!=3)printf("usage:cmd")tck=sysconf(_SC_CLK_TCK)start=times(&stm)if((srcfd=open(argv[1],O_RDONLY))==-1){error("open%serror",argv[1])exit(0)}if((dstfd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0666))==-1){error("creat%serror",argv[2])exit(0)}fstat(srcfd,&filestat)if(lseek(dstfd,filestat.st_size,SEEK_SET)==-1){error("lseekerror")exit(0)}if(write(dstfd,"",1)!=1){error("writeerror")exit(0)}cp_map(srcfd,dstfd,filestat.st_size)close(srcfd)close(dstfd)end=times(&ntm)printf("copying%sto%susingcp_map:filesize=%luMBytesUsing%fseconds\n",argv[1],argv[2],filestat.st_size>>20,(end-start)/(double)tck)sprintf(cmdline,"rm-f%s",argv[2])system(cmdline)return0}inlineintcp_rw(intsrcfd,intdstfd,char*buf,intlen){intnreadwhile((nread=read(srcfd,buf,len))>0){if(write(dstfd,buf,nread)!=nread){error("writeerror")return-1}}if(nread==-1){error("readerror")return-1}return0}inlineintcp_map(intsrcfd,intdstfd,size_tlen){char*src,*dstif((src=mmap(0,len,PROT_READ,MAP_SHARED,srcfd,0))==MAP_FAILED){error("mmapsrcerror")return-1}if((dst=mmap(0,len,PROT_WRITE,MAP_SHARED,dstfd,0))==MAP_FAILED){error("mmapdsterror")return-1}if(memcpy(dst,src,len)==NULL){error("memcpyerror")return-1}munmap(src,len)munmap(dst,len)return0}运行,拷贝一个1.1G的文件,得到如下结果[root@gardencopy]#./copy/home/ker.tgz./ker.tgzcopying/home/ker.tgzto./ker.tgzusingcp_map:filesize=1030MBytesUsing61.900000secondscopying/home/ker.tgzto./ker.tgzusingcp_rw:filesize=1030MBytesUsing34.330000seconds使用read/write的方法居然比mmap的快一倍,这是怎么回事呢?理论上mmap系统调用只进行了一次,而且拷贝文件是直接在内核空间进行的,read/write则需要通过系统调用把内核空间的缓存复制到用户空间,再将用户空间缓存复制到内核空间,拷贝次数明显多了一个呢?速度为什么于理论预测的不一致呢?Linux系统中的一切都是从根/目录开始的,并按照文件层次化标准(FHS)采用树形结构来存放文件,以及常见目录的用途。Linux文件存储结构:
/
/root /bin/boot/dev/etc/home/var/lib/usr/media/tmp/proc
II I
/root/Desktop /root/Media /usr/bin /usr/lib
/boot 开机所需文件-内核、开机菜单以及所需配置文件等
/dev 以文件形式存放任何设备与接口
/etc 配置文件
/home 用户家文件
/bin 存放单用户模式下还可以 *** 作的命令
/lib开机时用到的函数库,以及/bin与/sbin下面的命令要调用的函数
/sbin 开机过程中需要的命令
/media 用于挂载设备文件的目录
/opt 放置第三方的软件
/root 系统管理员的家目录
/srv 一些网络服务的数据文件目录
/tmp 任何人都可使用的共享临时目录
/proc 虚拟文件系统,例如系统内核、进程、外部设备及网络状态等
/usr/local 用户自行安装的软件
/var 主要存放日志等经常变化的文件
linux中SCSI\SATA\U盘的命名规则为/dev/sd[a-p]
硬盘设备是由大量的扇区组成的,每个扇区的容量为512字节。其中第一个扇区保存主引导记录与分区表信息(446字节),分区表64字节,结束字符2字节;其中分区表中每记录一个分区信息就需要占用16字节,这样一来最多只有4个分区信息可以写到第一个扇区中,这四个分区就是主分区。为了解决分区数不够的问题就要将第一个扇区中的分区表中16字节(扩展分区)拿来指向另外一个分区
主分区或扩展分区的编号从1开始,到4结束
逻辑分区的编号从5开始
举个栗子:
主分区1 sda1 主分区2 sda2 主分区3 sda3 扩展分区
I
逻辑分区1 sda5 逻辑分区2 sda6
PS:/dev中sda之所以是a并不是由插槽决定的,而是由系统内核的识别顺序来决定的
PS2:可有手动指定分区的数字编号所以并不能以编号来判定硬盘位置是设备上的第几个
PS3:扩展分区其实并不是一个真正的分区,而更像是一个占用16个字节分区表空间的指针-----一个指向另外一个分区的指针
为什么一般看不见sda4?
通常硬盘分区的二种方式,4p,3p+e,也就是说可以分为4个主分区或者3个主分区加一个扩展分区如果使3p+e的话那么久不存在第4个主分区而是将第四个主分区的位置换为了扩展分区而扩展分区的第一个逻辑分区会被命名为sda5
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)