URN Logo
UNIX Resources » Linux » China Linux Forum » C/C++编程版 » 14 » 求文件拷贝函数
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
求文件拷贝函数
求文件拷贝函数 - linux_tiantian [2006-05-23 17:25 | 112 byte(s)]
 
Re: 求文件拷贝函数 - lonelyflyer [2006-05-24 15:57 | 323 byte(s)]
 
Re: 求文件拷贝函数 - linux_tiantian [2006-05-25 14:21 | 20 byte(s)]
 
Re: 求文件拷贝函数 - zhllg [2006-05-25 11:56 | 114 byte(s)]
 
Re: 求文件拷贝函数 - lonelyflyer [2006-05-25 12:48 | 433 byte(s)]
 
Re: 求文件拷贝函数 - zhllg [2006-05-25 12:52 | 84 byte(s)]
 
Re: 求文件拷贝函数 - Atu [2006-05-25 14:14 | 1,113 byte(s)]
 
Re: 求文件拷贝函数 - lonelyflyer [2006-05-25 15:13 | 249 byte(s)]
 
Re: 求文件拷贝函数 - zhllg [2006-05-25 15:45 | 191 byte(s)]
 
Re: 求文件拷贝函数 - Atu [2006-05-25 16:27 | 3,042 byte(s)]
 
Re: 求文件拷贝函数 - zhllg [2006-05-25 16:59 | 230 byte(s)]
 
Re: 求文件拷贝函数 - lonelyflyer [2006-05-25 15:32 | 99 byte(s)]
 
Re: 求文件拷贝函数 - phus [2006-05-25 14:39 | 1,613 byte(s)]
 
Re: 求文件拷贝函数 - phus [2006-05-25 14:46 | 246 byte(s)]
 
Re: 求文件拷贝函数 - woshiwo [2006-05-25 15:03 | 186 byte(s)]
 
Re: 求文件拷贝函数 - phus [2006-05-25 15:08 | 191 byte(s)]
 
Re: 求文件拷贝函数 - smalllight [2006-05-23 20:53 | 170 byte(s)]
 
Re: 求文件拷贝函数 - Atu [2006-05-24 08:32 | 357 byte(s)]
 
Re: 求文件拷贝函数 - smalllight [2006-05-24 09:00 | 456 byte(s)]
 
Re: 求文件拷贝函数 - Atu [2006-05-24 10:17 | 987 byte(s)]
 
Re: 求文件拷贝函数 - seasoblue [2006-05-24 17:17 | 122 byte(s)]
 
Re: 求文件拷贝函数 - woshiwo [2006-05-24 21:21 | 151 byte(s)]
 
Re: 求文件拷贝函数 - newroot [2006-05-24 21:30 | 118 byte(s)]
 
Re: 求文件拷贝函数 - smalllight [2006-05-24 13:52 | 672 byte(s)]
 
Re: 求文件拷贝函数 - hsen [2006-05-27 15:51 | 127 byte(s)]
 
Re: 求文件拷贝函数 - smalllight [2006-05-27 21:49 | 177 byte(s)]
 
Re: 求文件拷贝函数 - hsen [2006-05-29 08:18 | 195 byte(s)]
 
Re: 求文件拷贝函数 - hsen [2006-05-29 08:14 | 140 byte(s)]
 
Re: 求文件拷贝函数 - tuboshu2811 [2006-05-24 15:18 | 98 byte(s)]
 
Re: 求文件拷贝函数 - KingArthur [2006-05-24 10:15 | 342 byte(s)]
 
Re: 求文件拷贝函数 - newroot [2006-05-23 21:38 | 22 byte(s)]
 
Subject: 求文件拷贝函数
Author: linux_tiantian    Posted: 2006-05-23 17:25    Length: 112 byte(s)
[Original] [Print] [Top]
各位高手!大家都知道用CP命令可以实现文件的任意拷贝,但是现在我要用程序来实现这个功能,有没有现成的函数啊?
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: smalllight    Posted: 2006-05-23 20:53    Length: 170 byte(s)
[Original] [Print] [Top]
方法1.
sprintf(cmd_line,"cp %s %s",file_s,file_o);
system(cmd_line);
方法2.打开第一个文一点一点的读出来直接写到另一个件里,就可以了。
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: newroot    Posted: 2006-05-23 21:38    Length: 22 byte(s)
[Original] [Print] [Top]
system可以这么用吗!?
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: Atu    Posted: 2006-05-24 08:32    Length: 357 byte(s)
[Original] [Print] [Top]
回答问题,精神可嘉,但是不知道就不要乱说

方法1.的语法是错误的 int system(const char *string);

方法2.也有问题。

正确做法是:
1. 打开两个文件A (O_RDONLY), B(O_WRONLY|O_CREAT),
2. 准备一个buffer(系统的cp命令用的是一个4k长度的buffer),
3. 从A读,写入B.

[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: smalllight    Posted: 2006-05-24 09:00    Length: 456 byte(s)
[Original] [Print] [Top]
打开两个文件A (O_RDONLY), B(O_WRONLY|O_CREAT,
打开件a(O_RDONLY)有这样的函数??????????
你不会也不要乱讲。
其实我告诉的只是一个方法。
用system的确可以实现拷。第二个你说的还是从一个文件里面读出写到另一个件里和我的有什么不同吗。
只不过你说的更祥细一点。不过我认为从一个文件里面读数据当然要用buffer太显然的问题就不要讲了吧。
你是不是还要告诉人家。定义buffer用char buffer[4*1024],等等。
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: KingArthur    Posted: 2006-05-24 10:15    Length: 342 byte(s)
[Original] [Print] [Top]
火气不要太大,错了就要虚心一点,也没什么大不了的.

Atu的意思显然是说用open来打开文件A和B,open的第二个参数(flags)分别使用O_RDONLY和O_WRONLY|O_CREAT.你要是用过open的话就不可能误解.

至于第二个问题,你说"一行一行的读出来",我想Atu是针对这个的吧.只有文本文件才有行的概念,而cp所处理的显然不仅仅是文本文件.
----
我只是个coder
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: Atu    Posted: 2006-05-24 10:17    Length: 987 byte(s)
[Original] [Print] [Top]
> 你不会也不要乱讲。
我不会的不会乱说的,至少我在这里回答问题,基本都是实际验证过的。
就象刚才说的缓冲区长度4k,我就是实际检查了cp所使用的缓冲区的长度,

缓冲区长度关系到文件拷贝的性能,我也没这个经验,
所以,实际查看了我的机器上/bin/cp使用的缓冲区长度,

说你不对,不委屈你,
你告诉人家一行一行复制,是打算让人家用fgets()去读源文件?
同样是buffer,是按行读,还是按长度读,是绝对的不同,这个不需要我解释吧

至于O_RDONLY,O_WRONLY,O_CREAT,我只是把cp调用open的标志抄过来了,
给别人一个参考而已,
如果你看到这些标记还不知道它的含义,只能说你太菜了,或者是成心装糊涂

顺便这里补充一下吧,cp在打开文件的时候,实际还有一个O_LARGEFILE选项,
如果程序不准备处理大于2G文件的话,这个选项可以不用的。

> 你是不是还要告诉人家。定义buffer用char buffer[4*1024],等等。
说详细一点总不是坏事吧?

[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: smalllight    Posted: 2006-05-24 13:52    Length: 672 byte(s)
[Original] [Print] [Top]
我不明白的是,你可以a(O_RDONLY)
我为什么就不可以system("cp %s %s",file_s,file_o);
我这句有语法错误.你的a(O_RDONLY)难道没有语法错误?????????
其实我们都是在告诉一种法方法.没必要扣那么细吧.
char cmdline[256];
sprintf(cmdline,"cp %s %s",file_s,file_o);//file_o,file_s是存放源文件名,和目标文件名的字符串的首址
system(cmdline);
这样总可以了吧
我希望你能明白我也是在尽力的帮助别人,没有乱讲.我说的方法也都是经过验证的
fgets我还真没想用这个函数,
我是想用fopen打开一个文件然后用fread去读然后用fwrite去写一行一行是写得有点不好,因为二进制文件不是以行的.我表达欠妥.
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: tuboshu2811    Posted: 2006-05-24 15:18    Length: 98 byte(s)
[Original] [Print] [Top]
两位大虾在争论中详细讲解了几种用法,令我受益匪浅,谢谢谢谢



----
linux starting。。。
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: lonelyflyer    Posted: 2006-05-24 15:57    Length: 323 byte(s)
[Original] [Print] [Top]
int src = open ("srcfile", O_RDONLY);
int dst = open ("dstfile", O_RDWR|O_TRUNC|O_CREAT, 0666);
struct stat fst;
fstat (src, &fst);
off_t offset = 0;
sendfile (dst, src, &offset, fst.st_size);
----
mount -o sync,dirsync
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: seasoblue    Posted: 2006-05-24 17:17    Length: 122 byte(s)
[Original] [Print] [Top]
其实大家都是讲实现的方法而已, 没必要那么细. 至少smalllight的第1个方法是可行的.
Atu说话有点让人下不来吧? 呵呵~~~
----
喜欢在海里游的鱼儿。。。。
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: woshiwo    Posted: 2006-05-24 21:21    Length: 151 byte(s)
[Original] [Print] [Top]
很对。最重要的是方向上的提示,细节的东西可以自己去解决。其实只要有人告诉我一个是system-cp,一个是read-write就足够了。不过Atu的敬业和细致还是值得称道的。
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: newroot    Posted: 2006-05-24 21:30    Length: 118 byte(s)
[Original] [Print] [Top]
呵呵,看来大家都是比较认真的嘛, 中国要是多一些像上面几位兄弟这么认真的话,会是怎样.

以和为贵!!!呵呵!!
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: zhllg    Posted: 2006-05-25 11:56    Length: 114 byte(s)
[Original] [Print] [Top]
还是sendfile的好啊
不需要用户层buffer
速度快啊
不过可惜的是似乎output fd必须是个socket
----
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: lonelyflyer    Posted: 2006-05-25 12:48    Length: 433 byte(s)
[Original] [Print] [Top]
在solaris下是可以处理两个磁盘文件的,linux下好像不行,我试不通,不过文档也没有否定,怕是还没完全实现罢

Either or both of these file descriptors may refer to a socket (but see below)

Presently the descriptor from which data is read cannot correspond to a socket, it must correspond to a file which
supports mmap()-like operations.
----
mount -o sync,dirsync
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: zhllg    Posted: 2006-05-25 12:52    Length: 84 byte(s)
[Original] [Print] [Top]
是的
目前如果output fd不是socket的话,Linux下sendfile会失败
EINVAL
----
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: Atu    Posted: 2006-05-25 14:14    Length: 1,113 byte(s)
[Original] [Print] [Top]
>目前如果output fd不是socket的话,Linux下sendfile会失败
>EINVAL

是否是内核版本问题?
我测试,似乎是可用的,代码如下(简陋了一点)
内核版本:2.4.21-20


$ cat a.c
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
int s = open("/boot/vmlinuz-2.4.21-20.EL", O_RDONLY);
int d = open("output", O_WRONLY | O_CREAT, 0600);
off_t off = 0;
ssize_t size = sendfile(d, s, &off, 10000000);
printf("size = %d, off = %d ", size, off);
}

$ ./a
size = 1243768, off = 1243768

$ md5sum output /boot/vmlinuz-2.4.21-20.EL
a7a6a1d88660615f357fef276140ddd7 output
a7a6a1d88660615f357fef276140ddd7 /boot/vmlinuz-2.4.21-20.EL


[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: linux_tiantian    Posted: 2006-05-25 14:21    Length: 20 byte(s)
[Original] [Print] [Top]
谢谢各位!我已经搞定
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: phus    Posted: 2006-05-25 14:39    Length: 1,613 byte(s)
[Original] [Print] [Top]
俺没测试成功。于是写了个函数来模仿sendfile.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>

ssize_t sendfile_mmap(int out_fd, int in_fd, off_t *offset, size_t count)
{
char *in_data_ptr;
int n;

in_data_ptr = mmap(NULL, count, PROT_READ, MAP_PRIVATE, in_fd, 0);
if(in_data_ptr == NULL)
{
return -1;
}
n = write(out_fd, in_data_ptr, count);
munmap(in_data_ptr, count);
*offset = n;

return n;
}

int main(int argc, char *argv[])
{
int in_fd, out_fd;
size_t datalen;
off_t of;

in_fd = open("/home/phus/downloads/1.jpg", O_RDONLY);
out_fd = open("/home/phus/downloads/2.jpg", O_RDWR, 0644);
datalen = lseek(in_fd, 0L, 2);
sendfile_mmap(out_fd, in_fd, &of, datalen);
printf("::%ld ", of);
close(in_fd);
close(out_fd);
return 0;
}

phus@localhost /home/phus/downloads $ md5sum 1.jpg 2.jpg
d6aec64f998b5290566ac063645d7287 1.jpg
d6aec64f998b5290566ac063645d7287 2.jpg

测试可行
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: phus    Posted: 2006-05-25 14:46    Length: 246 byte(s)
[Original] [Print] [Top]
本来想用两次mmap然后在memcpy的。
但是用lseek出来的空洞文件不能mmap, 当然是bus error了。
不知有没有解决办法。

用strace跟了一下dd if=/dev/zero of=./3.jpf bs=1024, 似乎dd也是用write, 不过说不定有什么库函数的封装.
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: woshiwo    Posted: 2006-05-25 15:03    Length: 186 byte(s)
[Original] [Print] [Top]
>>用strace跟了一下dd if=/dev/zero of=./3.jpf bs=1024, 似乎dd也是用write, 不过说不定有什么库函数的封装.
猜想这里应该是设备驱动层的write接口,而不是普通文件的write
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: phus    Posted: 2006-05-25 15:08    Length: 191 byte(s)
[Original] [Print] [Top]
呵呵, 应该是这样的。

不过我的意思是说:"用户程序生成文件的方法就只有write了吗?"
有没有其它办法, 比如系统调用(这个不太可能), 封装库好的函数(似乎也没有).
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: lonelyflyer    Posted: 2006-05-25 15:13    Length: 249 byte(s)
[Original] [Print] [Top]
是啊,在2.4内核下就可以,看了一下,2.4的sys_sendfile实现在mm/filemap.c,2.6的sys_sendfile实现在fs/read_write.c,而且实现有些不同,关键可能在2.4的common_sendfile和2.6的do_sendfile,其中有几处返回 EINVAL。或许是2.6的一个bug,熟悉内核的朋友可否解释一下
----
mount -o sync,dirsync
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: lonelyflyer    Posted: 2006-05-25 15:32    Length: 99 byte(s)
[Original] [Print] [Top]
怀疑do_sendfile里的这一行
retval = security_file_permission (out_file, MAY_WRITE);
----
mount -o sync,dirsync
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: zhllg    Posted: 2006-05-25 15:45    Length: 191 byte(s)
[Original] [Print] [Top]
有没有可能是glibc封装的呢
不知Atu和lonelyflyer有没有用strace看过?
二位用的是哪一个2.4的系统?

我总觉得有点奇怪
这么好的特性,为什么不带入2.6呢?
----
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: Atu    Posted: 2006-05-25 16:27    Length: 3,042 byte(s)
[Original] [Print] [Top]
我把strace结果贴给你看吧
sendfile确实是一个专门的系统调用。

OS: redhat-release-3AS-7.3


$ strace ./a >/dev/null
execve("./a", ["./a"], [/* 28 vars */]) = 0
uname({sys="Linux", node="linux", ...}) = 0
brk(0) = 0x86da000
open("/etc/ld.so.preload", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=17, ...}) = 0
old_mmap(NULL, 17, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = 0xb75f7000
close(3) = 0
open("/etc/libcwait.so", O_RDONLY) = 3
read(3, "177ELF1113313404"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=4431, ...}) = 0
old_mmap(NULL, 5912, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x61e000
old_mmap(0x61f000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0) =
0x61f000
close(3) = 0
munmap(0xb75f7000, 17) = 0
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=86552, ...}) = 0
old_mmap(NULL, 86552, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb75e2000
close(3) = 0
open("/lib/tls/libc.so.6", O_RDONLY) = 3
read(3, "177ELF111331200X1"..., 512) = 512
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0xb75e1000
fstat64(3, {st_mode=S_IFREG|0755, st_size=1568924, ...}) = 0
old_mmap(NULL, 1276876, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x111000
old_mmap(0x243000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x131000) =
0x243000
old_mmap(0x247000, 7116, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
-1, 0) = 0x247000
close(3) = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xb75e17c0, limit:1048575,
seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0,
useable:1}) = 0
munmap(0xb75e2000, 86552) = 0
open("/boot/vmlinuz-2.4.21-20.EL", O_RDONLY) = 3
open("output", O_WRONLY|O_CREAT, 0600) = 4
sendfile(4, 3, [0], 10000000) = 1243768
fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfffb950) = -1 ENOTTY (Inappropriate ioctl
for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0xb75f7000
write(1, "size = 1243768, off = 1243768 ", 30) = 30
munmap(0xb75f7000, 4096) = 0
exit_group(30) = ?
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: zhllg    Posted: 2006-05-25 16:59    Length: 230 byte(s)
[Original] [Print] [Top]
前面没仔细看,manpage里有这一句
In Linux 2.4 and earlier, out_fd could refer to a regular file, and send-
file() changed the current offset of that file.
还不清楚为什么2.6不能再引用常规文件
----
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: hsen    Posted: 2006-05-27 15:51    Length: 127 byte(s)
[Original] [Print] [Top]
你的方法是有问题的,要是文件名中有空格怎么办?如果有分号呢?要是更狠一点我把file_s定义为'a b;' file_o 定义为'rm /etc/passwd' 呢
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: smalllight    Posted: 2006-05-27 21:49    Length: 177 byte(s)
[Original] [Print] [Top]
你说的那种情况,要有root权限才可以执行的,所以在linux,root 的权限是不能随便让人获得的.那是非常危险的.有空格的那种情部你要自已考虑i,不过(如果我没记错的话)文件名里是不欢许有;号的吧,
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: hsen    Posted: 2006-05-29 08:14    Length: 140 byte(s)
[Original] [Print] [Top]
我当然知道怎么做,我的意思是你用这种system的方法不可取,等于自己要做很多额外的工作,不管文件名是否允许有分号,只要用户输了进来,你就头大了。
[Original] [Print] [Top]
Subject: Re: 求文件拷贝函数
Author: hsen    Posted: 2006-05-29 08:18    Length: 195 byte(s)
[Original] [Print] [Top]
谁说文件名中不允许分号的?

firewall:/tmp# touch 'adb;dedf;a'
firewall:/tmp# ls -l
total 0
-rw-r--r-- 1 root root 0 May 29 08:29 adb;dedf;a
[Original] [Print] [Top]
« Previous thread
xp下vc++里编的程序怎么移植到linux下[我是新手]
C/C++编程版
14
Next thread »
请教一个多线程问题
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 03:52:06, cost 0.077370882034302 ms.