Chinaunix

标题: APUE Exercise 4.6 [打印本页]

作者: tyc611    时间: 2007-09-04 23:13
标题: APUE Exercise 4.6
Write a utility like cp(1) that copies a file containing holes, without writing the bytes of 0 to the output file.

没想出来,向大家请教一下,谢谢!
作者: ypxing    时间: 2007-09-04 23:38
先求源文件的大小
根据大小copy文件
然后再移动目的文件指针,如何?

有点想当然了,呵呵
俺再想想


原帖由 tyc611 于 2007-9-4 23:13 发表

没想出来,向大家请教一下,谢谢!

[ 本帖最后由 ypxing 于 2007-9-4 23:45 编辑 ]
作者: tyc611    时间: 2007-09-04 23:51
原帖由 ypxing 于 2007-9-4 23:38 发表
先求源文件的大小
根据大小copy文件
然后再移动目的文件指针,如何?

有点想当然了,呵呵
俺再想想




1. 如何计算源文件大小?
2. 你怎么知道file hole在哪?
作者: ypxing    时间: 2007-09-05 00:00
stat不能求出大小吗?
只是hole不知在哪里

原帖由 tyc611 于 2007-9-4 23:51 发表


1. 如何计算源文件大小?
2. 你怎么知道file hole在哪?

作者: antigloss    时间: 2007-09-05 00:10
原帖由 ypxing 于 2007-9-5 00:00 发表
stat不能求出大小吗?
只是hole不知在哪里


stat算出来的大小似乎就包括了hole
作者: tyc611    时间: 2007-09-05 00:13
原帖由 ypxing 于 2007-9-5 00:00 发表
stat不能求出大小吗?
只是hole不知在哪里



stat获得的也是加上file hole的大小
作者: Jiangge    时间: 2007-09-05 09:57
hole --默认都是0

stat的是文件的大小,包括hole
作者: tyc611    时间: 2007-09-05 18:34
顶一下
作者: MMMIX    时间: 2007-09-05 21:27
原帖由 Jiangge 于 2007-9-5 09:57 发表
hole --默认都是0

你的意思是"hole 在读取时相当于那里面都是 0" 么?

这个功能实现的关键就是不写入读到的 0. 而只是通过 lseek(2) 或类似函数修改 file offset.
作者: tyc611    时间: 2007-09-05 22:32
原帖由 MMMIX 于 2007-9-5 21:27 发表

你的意思是"hole 在读取时相当于那里面都是 0" 么?

用read读的结果就是0
这个功能实现的关键就是不写入读到的 0. 而只是通过 lseek(2) 或类似函数修改 file offset.

关键是怎么判断?
作者: JohnBull    时间: 2007-09-05 23:18
如果源文件中出现整块的0,不要执行write(2),改用lseek(2)即可。
作者: tyc611    时间: 2007-09-05 23:52
原帖由 JohnBull 于 2007-9-5 23:18 发表
如果源文件中出现整块的0,不要执行write(2),改用lseek(2)即可。

怎么知道出现了整块的0?还是read先?
如果刚好有数据也是0且挨着hole呢?
作者: ivhb    时间: 2007-09-05 23:59
int
main(void)
{
  int c;
  while ((c = getchar()) != EOF)
    if (c != 0)
       putchar(c);
}

./a.out < a > b
这样不可以么?
不能说hole就是一定要lseek过的吧。事实上,lseek跳过1个字节和写入一个0是一样的。
作者: tyc611    时间: 2007-09-06 00:07
原帖由 ivhb 于 2007-9-5 23:59 发表
int
main(void)
{
  int c;
  while ((c = getchar()) != EOF)
    if (c != 0)
       putchar(c);
}

./a.out < a > b
这样不可以么?
不能说hole就是一定要lseek过的吧。事实上,lseek跳过1个字节 ...

你这是把读的数据为0的扔掉,当然不可以
并且,我觉得应该从底层来考虑,用库函数是实现不了的吧
作者: ivhb    时间: 2007-09-06 00:14
我觉得你想的太复杂了。APUE基本上还是介绍系统接口。而不是告诉你系统的实现细节。
这个问题,不同的文件系统应该是不同的实现。如何能做到?
作业上也没有说什么文件系统吧?
作者: tyc611    时间: 2007-09-06 23:35
原帖由 ivhb 于 2007-9-6 00:14 发表
我觉得你想的太复杂了。APUE基本上还是介绍系统接口。而不是告诉你系统的实现细节。
这个问题,不同的文件系统应该是不同的实现。如何能做到?
作业上也没有说什么文件系统吧?

我上面说的就是从系统接口考虑,而不应该从函数库考虑
另外,只要解决了问题就行,不管啥途径哈
作者: MMMIX    时间: 2007-09-10 21:02
原帖由 ivhb 于 2007-9-5 23:59 发表
事实上,lseek跳过1个字节和写入一个0是一样的。

事实上,它们完全是两回事.
作者: MMMIX    时间: 2007-09-10 21:07
原帖由 tyc611 于 2007-9-5 23:52 发表

怎么知道出现了整块的0?还是read先?

这个很好判断. 其实只要是 0 就可以了, 没必要整块(单独一个字节为 0 算是整块么?).
如果刚好有数据也是0且挨着hole呢?

这种情况的话这个 hole 前面的数据 0 就会被当作该 hole 的一部分. 这也是没办法的事情, 好在这样并不影响拷贝后文件的读取结果.
作者: reedwind    时间: 2007-09-10 21:14
我是新手刚开始看apue(第一版)
最近刚看到第四章也是不会这个题(因为没答案)

我还没明白题目的意思
它是忽略所有的hole,不把hole算在文件内容里面吗?
这样下来,程序执行完成后,新文件的大小(sizeof)是不是就要比旧文件的大小少了那些个hole呢?
还有这里的hole以0来算,这个0应该跟c里面字符串常量里面那个h e l l o \0中的那个\0一样吗?
作者: ivhb    时间: 2007-09-11 08:58
原帖由 MMMIX 于 2007-9-10 21:02 发表

事实上,它们完全是两回事.


呵呵,你要说文件系统内部肯定是有区别。这个区别可能是谁也说不清楚的区别。
从应用程序角度(只要你还是用unix提供的系统接口来读取文件,而不是绕过接口)上看,你没有办法区别hole和的nil。不是一回事又是什么?




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