Chinaunix

标题: 文件复制时如何处理文件中的空洞(holes)?? [打印本页]

作者: redog    时间: 2005-11-23 15:49
标题: 文件复制时如何处理文件中的空洞(holes)??
实在想不出有什么办法呀
作者: assiss    时间: 2005-11-23 15:50
什么叫空洞?
作者: renstone921    时间: 2005-11-23 17:10
stat确定文件尺寸。
分配足够空间,读入。
作者: cmh_2003    时间: 2005-11-23 17:59
贴段写带空洞文件的代码~  希望有帮助
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include"ourhdr.h"

char buf1[]="abcdefghij";
char buf2[]="ABCDEFGHIJ";

int
main(void)
{
  int fd;
  if((fd=creat("file.hole",FILE_MODE))<0)
    err_sys("creat error");
  if(write(fd,buf1,10)!=10)
    err_sys("buf1 write error");
  /* offset now=10 */
  if(lseek(fd,40,SEEK_SET)==-1)
    err_sys("lseek error");
  /* offset now=40 */
  if(write(fd,buf2,10)!=10)
    err_sys("buf2 write error");
  /* offset now=50*/
  exit(0);
}
作者: redog    时间: 2005-11-23 18:09
标题: 回复 4楼 cmh_2003 的帖子
谢谢楼上两位
用stat读的大小,包含了空洞的大小, 而我复制时想去掉空洞部分,怎样做才能跳过空洞??
作者: 圆点坐标    时间: 2005-11-23 19:51
空洞不占用磁盘空间,只是打开文件时在内核用一个值为0的数据结构表示
作者: anhk    时间: 2007-02-01 14:02
大家好,我遇到同样问题,怎么判断文件的某部分是空洞?
或者说复制的时候,我不想复制空洞的那部分0,怎么处理?
我还需要copy之后保留空洞的地方, 用lseek实现?
谢谢

[ 本帖最后由 anhk 于 2007-2-1 14:33 编辑 ]
作者: caijimin    时间: 2007-02-01 14:38
这应该称作sparse file(稀疏文件),对稀疏文件的判断只能是大致的方法。
stat除了看到size外,还可以看到占用的磁盘block数,假如一个block是4K字节,
block数乘以4k得到的结果远小于文件size,大致可以认为是sparse file。

正常来说看到连续的一大堆0可认为是sparse, Linux下的cp命令有参数
--sparse=WHEN
              control creation of sparse files
有兴趣可以看cp的source code
作者: anhk    时间: 2007-02-01 15:37
原帖由 caijimin 于 2007-2-1 14:38 发表
这应该称作sparse file(稀疏文件),对稀疏文件的判断只能是大致的方法。
stat除了看到size外,还可以看到占用的磁盘block数,假如一个block是4K字节,
block数乘以4k得到的结果远小于文件size,大致可以认为是 ...


谢谢,我去看看CP的代码,请问cp的代码是不是在glibc里边?

[ 本帖最后由 anhk 于 2007-2-1 15:51 编辑 ]
作者: anhk    时间: 2007-02-01 15:55
找到了,是在coreutils里边
作者: bleem1998    时间: 2007-02-01 15:57
每个字节都判断一下
如果是0就做一个lseek
这样行么
呵呵
作者: lonelyair    时间: 2007-02-01 17:00
原帖由 caijimin 于 2007-2-1 14:38 发表
这应该称作sparse file(稀疏文件),对稀疏文件的判断只能是大致的方法。
stat除了看到size外,还可以看到占用的磁盘block数,假如一个block是4K字节,
block数乘以4k得到的结果远小于文件size,大致可以认为是 ...

哪里有CP的source code?
作者: anhk    时间: 2007-02-01 17:07
原帖由 caijimin 于 2007-2-1 14:38 发表
这应该称作sparse file(稀疏文件),对稀疏文件的判断只能是大致的方法。
stat除了看到size外,还可以看到占用的磁盘block数,假如一个block是4K字节,
block数乘以4k得到的结果远小于文件size,大致可以认为是 ...

一个空洞文件,size = 11,  blksize = 4096, blocks = 8, blksize * blocks = 32768
怎么个比较法?

cp代码在coreutils里,有cp.c
作者: anhk    时间: 2007-02-01 17:07
原帖由 bleem1998 于 2007-2-1 15:57 发表
每个字节都判断一下
如果是0就做一个lseek
这样行么
呵呵


二进制文件怎么办?
不是所有文件都是文本的。

看了CP的代码,CP就是这么做的。。

[ 本帖最后由 anhk 于 2007-2-1 17:45 编辑 ]
作者: lonelyair    时间: 2007-02-01 17:19
原帖由 anhk 于 2007-2-1 17:07 发表

一个空洞文件,size = 11,  blksize = 4096, blocks = 8, blksize * blocks = 32768
怎么个比较法?

cp代码在coreutils里,有cp.c

谢了,下载去看看.
一直没找到.
作者: anhk    时间: 2007-02-01 17:40
原帖由 lonelyair 于 2007-2-1 17:19 发表

谢了,下载去看看.
一直没找到.


http://61.135.158.199/distfiles/
http://mirror.gentoo.gr.jp/distfiles
这是gentoo的源,里边有几乎所有常用的代码包

[ 本帖最后由 anhk 于 2007-2-1 17:41 编辑 ]
作者: caijimin    时间: 2007-02-01 17:50
原帖由 anhk 于 2007-2-1 17:07 发表

一个空洞文件,size = 11,  blksize = 4096, blocks = 8, blksize * blocks = 32768
怎么个比较法?

用du -h 看吧。另外size小于1个block的不能算是sparse吧
作者: anhk    时间: 2007-02-01 17:54

  1. root:temp# cp --sparse=never abc def
  2. root:temp# du abc def
  3. 8        abc
  4. 104      def
  5. root:temp# du -h abc def
  6. 8.0K     abc
  7. 104K     def
  8. root:temp#
复制代码


在linux系统的C语言里,怎么能判断出来呢?  read空洞文件和普通文件是一样的。
只能stat。
可是我stat却出现了上边的数据
原帖由 anhk 于 2007-2-1 17:07 发表

一个空洞文件,size = 11,  blksize = 4096, blocks = 8, blksize * blocks = 32768
怎么个比较法?

[ 本帖最后由 anhk 于 2007-2-1 17:56 编辑 ]
作者: anhk    时间: 2007-02-01 17:59
stat abc: size=100005 blksize=4096 blocks=16 blksize*blocks=65536
stat def: size=100005 blksize=4096 blocks=208blksize*blocks=851968

我闹不清楚这些是什么关系。。

还有,du def 是104K, 与100005怎么都转不到一起,用1000和1024都不行。。

[ 本帖最后由 anhk 于 2007-2-1 18:19 编辑 ]
作者: caijimin    时间: 2007-02-01 18:42
原帖由 anhk 于 2007-2-1 17:59 发表
stat abc: size=100005 blksize=4096 blocks=16 blksize*blocks=65536
stat def: size=100005 blksize=4096 blocks=208blksize*blocks=851968

我闹不清楚这些是什么关系。。

还有,du def 是104K, 与 ...


好像block size是512, 4096是IO block size
作者: langue    时间: 2007-02-01 18:47
原帖由 assiss 于 2005-11-23 15:50 发表
什么叫空洞?


我觉得应该问楼主,什么叫 “处理文件中的空洞”
作者: langue    时间: 2007-02-01 18:47
原帖由 lonelyair 于 2007-2-1 17:00 发表

哪里有CP的source code?


搜索一下 oldcp.c

--
作者: JohnBull    时间: 2007-02-01 22:57
无法精确判断。
cp的处理就是最合理的方法。
作者: anhk    时间: 2007-02-02 09:01
是这样的,我这里监控一些文件,但是不知道文件是否完整,我想根据是否有空洞来查看,或者看有没有其他的办法。
作者: anhk    时间: 2007-02-02 10:30
原帖由 langue 于 2007-2-1 18:47 发表


搜索一下 oldcp.c

--


oldcp.c

  1. main(argc,argv)
  2. char **argv;
  3. {
  4. char buf[512];
  5. int fold, fnew, n;
  6. char *p1, *p2, *bp;
  7. int mode;
  8.         if(argc != 3) {
  9.                 write(1,"Usage: cp oldfile newfile\n",26);
  10.                 exit();
  11.         }
  12.         if((fold = open(argv[1],0)) < 0){
  13.                 write(1,"Cannot open old file.\n",22);
  14.                 exit();
  15.         }
  16.         fstat(fold,buf);
  17.         mode = buf[2] & 037;
  18.         if((fnew = creat(argv[2],mode)) < 0){
  19.                 stat(argv[2], buf);
  20.                 if((buf[3] & 0100) != 0){
  21.                         p1 = argv[1] - 1;
  22.                         p2 = argv[2] - 1;
  23.                         bp = buf - 1;
  24.                         while(*++bp = *++p2);
  25.                         *bp = '/';
  26.                         p2 = bp;
  27.                         while(*++bp = *++p1)
  28.                                 if(*bp == '/')
  29.                                         bp = p2;
  30.                         if((fnew = creat(buf,mode)) < 0){
  31.                                 write(1,"Cannot creat new file.\n",23);
  32.                                 exit();
  33.                         }
  34.                 }else{
  35.                 write(1,"Cannot creat new file.\n",23);
  36.                 exit();
  37.                 }
  38.         }
  39.         while(n = read(fold, buf, 512))
  40.         if(n < 0){
  41.                 write(1,"Read error\n",11);
  42.                 exit();
  43.         }else
  44.                 if(write(fnew,buf,n) != n){
  45.                         write(1,"Write error.\n",13);
  46.                         exit();
  47.                 }
  48.         fstat(fnew,buf);
  49.         exit();
  50. }

复制代码

没有看到对空洞文件的处理




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2