Perl文件操作模块-File::Copy


Copy files or filehandles
该模块提供了两个基本功能,即复制和移动,这两个功能对于将文件的内容从一个地方获取到另一个地方非常有用。系内置模块。
所有函数成功时返回1,失败时返回0;$!将在遇到错误时保存当时的错误消息。
1.copy
copy函数接受两个参数:一个要从中复制的文件和一个要复制到的文件。其中一个参数可以是字符串、FileHandle引用或FileHandle glob。如果目标(第二个参数)已经存在并且是一个目录,而源(第一个参数)不是文件句柄,则源文件将使用与源文件相同的基本名称复制到目标指定的目录中。
可以使用语法使用File::Copy "cp"来获取此函数的cp别名。语法完全相同。行为也几乎相同:从2.15版本开始,cp将像shell实用程序cp一样保留源文件的权限位,而copy则使用目标文件的默认权限(这可能取决于进程的umask、文件所有权、继承的ACL等)。如果设置权限时出错,cp将返回0,而不管文件是否成功复制。
用法小结如下:
1.两个参数都可以是文件或文件句柄或者文件句柄通配,第一个参数指定源,第二个参数指定目标
如果第一个参数是文件句柄,那么将直接从文件句柄来读取数据,如果这个参数是文件,那么将打开这个文件来读取数据
第二个参数是数据的写入目标
2.如果目标文件不存在,但父目录存在,则创建该目标文件,但如果父目录也不存在,则报错
3.如果目标文件存在,则覆盖该目标文件,不会给出任何提示
4.如果目标是一个已存在的目录,且源不是一个文件句柄,则拷贝到目标目录中,如果源是一个文件句柄,将报错
5.源和目标不能是同一文件
6.因为是拷贝操作,所以可以跨文件系统拷贝
7.第三个可选参数用于设置拷贝时的缓冲大小。对于文件来说,一般缓冲大小是整个文件(但最大2MB),对于不关联实体文件的文件句柄(如套接字文件句柄),默认为1K大小
8.cp可以替换copy。它们的参数模式完全一致,但cp会保留源文件的属性,而copy则是采用目标文件的默认属性。此外,cp在遇到权限错误的时候返回0,而不管文件是否成功拷贝
9.强烈建议:如果可以,都使用文件名而不是文件句柄。如果要使用文件句柄,则采用binmode模式的文件句柄,以免丢失某些数据
10.File::Copy模块无法操作目录,所以copy无法复制目录
2.move
move函数还接受两个参数:要移动的文件的当前名称和预期名称。如果目标已经存在并且是目录,而源不是目录,则源文件将移动到到目标目录之下。
如果可能,move()将简单地重命名文件。否则它会将文件复制到新位置并删除原始文件。如果在复制和删除过程中发生错误,可能会在目标名称下留下文件的(可能是部分)副本。同'cp'指令一样,该函数有一个'mv'指令,并与其类似。
File::Copy模块提供了move函数,它可以跨文件系统移动文件。用法大致如下:
use File::Copy qw(move mv);
move("/dev1/sourcefile","/dev2/destinationfile");
mv("/dev1/sourcefile","/dev2/destinationfile");
mv("/dev1/sourcefile" => "/dev2/destinationfile");
用法小结如下:
1.File::Copy模块无法操作目录,所以move无法重命名或移动目录
2.move有两个参数,第一个是源,第二个是目标
3.如果目标是个已存在的目录,而源是个非目录,则源将被移动到目标目录内
4.如果可以,move在文件系统底层只是简单地重命名文件。否则(例如跨文件系统),将copy源文件到目标,然后删除源文件。如果这个copy+delete的过程中失败,则在目标路径下会遗留一个可能还未拷贝完成的副本
5.move可以用mv替代
6.可以采用shell交互的方式来取巧重命名:rename(old,new) or system("mv",old,new);
3.syscopy
其将所述第一参数中指定的文件复制到所述第二参数中所指定的文件并保留OS特定属性和文件结构。对于Unix系统,这相当于简单的复制例程,它不保留操作系统特定的属性。对于VMS系统,这将调用rmscope例程。对于OS/2系统,这将直接调用syscopy XSUB。对于Win32系统,这将调用Win32::CopyFile。
如果要复制的两个参数都不是文件句柄,则复制将执行输入文件到新输出文件的“系统复制”,以保留文件属性、索引文件结构等。缓冲区大小参数将被忽略。如果要复制的任何一个参数都是打开文件的句柄,则使用Perl运算符复制数据,并且不需要保存文件属性或记录结构。
4.rmscopy($from,$to[,$date_flag])
第一个和第二个参数可以是字符串、typeglob、typeglb引用或从IO::Handle继承的对象;它们在所有情况下都用于分别获取输入文件和输出文件的filespec。如果需要,输入文件的名称和类型将用作输出文件的默认值。
始终创建输出文件的新版本,该版本继承输入文件的结构和RMS属性,所有者和保护(可能还有时间戳)除外。输入文件中的所有数据都被复制到输出文件中;如果rmscope的前两个参数中有一个是文件句柄,则其位置不变(请注意,这意味着在rmscope返回后,指向输出文件的文件句柄将与该文件的旧版本相关联,而不是与新创建的版本相关联。)
第三个参数是整数标志,它告诉rmscope如何处理时间戳。如果小于0,则不会将输入文件的时间戳传播到输出文件。如果大于0,则将其解释为位掩码:如果设置了位0(LSB),则传播修订日期以外的时间戳;如果设置了位1,则传播修订日期。如果rmscope的第三个参数是0,那么它的行为与DCL COPY命令非常相似:如果输出文件的名称或类型是显式指定的,那么不会传播时间戳,但如果它们是从输入filespec中隐式获取的,那么会传播除修订日期之外的所有时间戳。如果未提供此参数,则默认为0。
5.重命名文件
rename函数可以重命名文件,也可以移动文件到其它目录。功能类似于unix下的mv命令。
rename old_name,new_name;
rename old_name => new_name; # 列表环境下,逗号可用胖箭头替换
但需要注意,rename函数无法跨文件系统移动文件,因为它的底层仅仅只是重命名,修改文件inode中的数据。跨文件系统移动文件,实际上是复制文件再删除源文件,它会导致inode号码改变,rename的本质是基于inode的,无法实现这样的功能。
rename "test2.log","test22.log" or die "Can't rename file1: $!";
rename "test22.log","/tmp/test23.log" or die "Can't rename file2: $!";
# 本操作将报错
rename "/tmp/test223.log","/boot/test223.log" or die "Can't rename file3: $!";
递归复制或移动可参考模块:File::Copy::Recursive。
示例用法
use File::Copy;
copy($oldfile, $newfile);
相当于
open(IN, "< $oldfile") or die "can't open $oldfile: $!";
open(OUT, "> $newfile") or die "can't open $newfile: $!";
$blksize = (stat IN)[11] || 16384; # preferred block size
while ($len = sysread IN, $buf, $blksize) {
if (!defined $len) {
next if $! =~ /^Interrupted/; # ^Z and fg
die "System read error: $!\n";
}
$offset = 0;
while ($len) { # Handle partial writes.
defined($written = syswrite OUT, $buf, $len, $offset) or die "System write error: $!\n";
$len -= $written;
$offset += $written;
};
}
close(IN);
close(OUT);
或调用系统的复制指令:
system("cp $oldfile $newfile"); # unix
system("copy $oldfile $newfile"); # dos, vms
File::Copy模块提供复制和移动功能。这些比求助于低级I/O调用更方便,并且比调用系统更便携。兼容环境更多;标准的Perl内置重命名(rename函数通常)没有。
use File::Copy;
copy("datafile.dat", "datafile.bak") or die "copy failed: $!";
move("datafile.dat", "datafile.new") or die "move failed: $!";
因为这些函数只返回一个简单的成功状态,所以无法轻易判断是哪个文件阻止了复制或移动,手动复制文件可以确定哪些文件没有复制。
类简化的more或less指令
use File::Copy qw(copy cp);
my $fn='freeoa.log';
copy($fn,\*STDOUT);
参考来源:
File::Copy
该模块提供了两个基本功能,即复制和移动,这两个功能对于将文件的内容从一个地方获取到另一个地方非常有用。系内置模块。
所有函数成功时返回1,失败时返回0;$!将在遇到错误时保存当时的错误消息。
1.copy
copy函数接受两个参数:一个要从中复制的文件和一个要复制到的文件。其中一个参数可以是字符串、FileHandle引用或FileHandle glob。如果目标(第二个参数)已经存在并且是一个目录,而源(第一个参数)不是文件句柄,则源文件将使用与源文件相同的基本名称复制到目标指定的目录中。
可以使用语法使用File::Copy "cp"来获取此函数的cp别名。语法完全相同。行为也几乎相同:从2.15版本开始,cp将像shell实用程序cp一样保留源文件的权限位,而copy则使用目标文件的默认权限(这可能取决于进程的umask、文件所有权、继承的ACL等)。如果设置权限时出错,cp将返回0,而不管文件是否成功复制。
用法小结如下:
1.两个参数都可以是文件或文件句柄或者文件句柄通配,第一个参数指定源,第二个参数指定目标
如果第一个参数是文件句柄,那么将直接从文件句柄来读取数据,如果这个参数是文件,那么将打开这个文件来读取数据
第二个参数是数据的写入目标
2.如果目标文件不存在,但父目录存在,则创建该目标文件,但如果父目录也不存在,则报错
3.如果目标文件存在,则覆盖该目标文件,不会给出任何提示
4.如果目标是一个已存在的目录,且源不是一个文件句柄,则拷贝到目标目录中,如果源是一个文件句柄,将报错
5.源和目标不能是同一文件
6.因为是拷贝操作,所以可以跨文件系统拷贝
7.第三个可选参数用于设置拷贝时的缓冲大小。对于文件来说,一般缓冲大小是整个文件(但最大2MB),对于不关联实体文件的文件句柄(如套接字文件句柄),默认为1K大小
8.cp可以替换copy。它们的参数模式完全一致,但cp会保留源文件的属性,而copy则是采用目标文件的默认属性。此外,cp在遇到权限错误的时候返回0,而不管文件是否成功拷贝
9.强烈建议:如果可以,都使用文件名而不是文件句柄。如果要使用文件句柄,则采用binmode模式的文件句柄,以免丢失某些数据
10.File::Copy模块无法操作目录,所以copy无法复制目录
2.move
move函数还接受两个参数:要移动的文件的当前名称和预期名称。如果目标已经存在并且是目录,而源不是目录,则源文件将移动到到目标目录之下。
如果可能,move()将简单地重命名文件。否则它会将文件复制到新位置并删除原始文件。如果在复制和删除过程中发生错误,可能会在目标名称下留下文件的(可能是部分)副本。同'cp'指令一样,该函数有一个'mv'指令,并与其类似。
File::Copy模块提供了move函数,它可以跨文件系统移动文件。用法大致如下:
use File::Copy qw(move mv);
move("/dev1/sourcefile","/dev2/destinationfile");
mv("/dev1/sourcefile","/dev2/destinationfile");
mv("/dev1/sourcefile" => "/dev2/destinationfile");
用法小结如下:
1.File::Copy模块无法操作目录,所以move无法重命名或移动目录
2.move有两个参数,第一个是源,第二个是目标
3.如果目标是个已存在的目录,而源是个非目录,则源将被移动到目标目录内
4.如果可以,move在文件系统底层只是简单地重命名文件。否则(例如跨文件系统),将copy源文件到目标,然后删除源文件。如果这个copy+delete的过程中失败,则在目标路径下会遗留一个可能还未拷贝完成的副本
5.move可以用mv替代
6.可以采用shell交互的方式来取巧重命名:rename(old,new) or system("mv",old,new);
3.syscopy
其将所述第一参数中指定的文件复制到所述第二参数中所指定的文件并保留OS特定属性和文件结构。对于Unix系统,这相当于简单的复制例程,它不保留操作系统特定的属性。对于VMS系统,这将调用rmscope例程。对于OS/2系统,这将直接调用syscopy XSUB。对于Win32系统,这将调用Win32::CopyFile。
如果要复制的两个参数都不是文件句柄,则复制将执行输入文件到新输出文件的“系统复制”,以保留文件属性、索引文件结构等。缓冲区大小参数将被忽略。如果要复制的任何一个参数都是打开文件的句柄,则使用Perl运算符复制数据,并且不需要保存文件属性或记录结构。
4.rmscopy($from,$to[,$date_flag])
第一个和第二个参数可以是字符串、typeglob、typeglb引用或从IO::Handle继承的对象;它们在所有情况下都用于分别获取输入文件和输出文件的filespec。如果需要,输入文件的名称和类型将用作输出文件的默认值。
始终创建输出文件的新版本,该版本继承输入文件的结构和RMS属性,所有者和保护(可能还有时间戳)除外。输入文件中的所有数据都被复制到输出文件中;如果rmscope的前两个参数中有一个是文件句柄,则其位置不变(请注意,这意味着在rmscope返回后,指向输出文件的文件句柄将与该文件的旧版本相关联,而不是与新创建的版本相关联。)
第三个参数是整数标志,它告诉rmscope如何处理时间戳。如果小于0,则不会将输入文件的时间戳传播到输出文件。如果大于0,则将其解释为位掩码:如果设置了位0(LSB),则传播修订日期以外的时间戳;如果设置了位1,则传播修订日期。如果rmscope的第三个参数是0,那么它的行为与DCL COPY命令非常相似:如果输出文件的名称或类型是显式指定的,那么不会传播时间戳,但如果它们是从输入filespec中隐式获取的,那么会传播除修订日期之外的所有时间戳。如果未提供此参数,则默认为0。
5.重命名文件
rename函数可以重命名文件,也可以移动文件到其它目录。功能类似于unix下的mv命令。
rename old_name,new_name;
rename old_name => new_name; # 列表环境下,逗号可用胖箭头替换
但需要注意,rename函数无法跨文件系统移动文件,因为它的底层仅仅只是重命名,修改文件inode中的数据。跨文件系统移动文件,实际上是复制文件再删除源文件,它会导致inode号码改变,rename的本质是基于inode的,无法实现这样的功能。
rename "test2.log","test22.log" or die "Can't rename file1: $!";
rename "test22.log","/tmp/test23.log" or die "Can't rename file2: $!";
# 本操作将报错
rename "/tmp/test223.log","/boot/test223.log" or die "Can't rename file3: $!";
递归复制或移动可参考模块:File::Copy::Recursive。
示例用法
use File::Copy;
copy($oldfile, $newfile);
相当于
open(IN, "< $oldfile") or die "can't open $oldfile: $!";
open(OUT, "> $newfile") or die "can't open $newfile: $!";
$blksize = (stat IN)[11] || 16384; # preferred block size
while ($len = sysread IN, $buf, $blksize) {
if (!defined $len) {
next if $! =~ /^Interrupted/; # ^Z and fg
die "System read error: $!\n";
}
$offset = 0;
while ($len) { # Handle partial writes.
defined($written = syswrite OUT, $buf, $len, $offset) or die "System write error: $!\n";
$len -= $written;
$offset += $written;
};
}
close(IN);
close(OUT);
或调用系统的复制指令:
system("cp $oldfile $newfile"); # unix
system("copy $oldfile $newfile"); # dos, vms
File::Copy模块提供复制和移动功能。这些比求助于低级I/O调用更方便,并且比调用系统更便携。兼容环境更多;标准的Perl内置重命名(rename函数通常)没有。
use File::Copy;
copy("datafile.dat", "datafile.bak") or die "copy failed: $!";
move("datafile.dat", "datafile.new") or die "move failed: $!";
因为这些函数只返回一个简单的成功状态,所以无法轻易判断是哪个文件阻止了复制或移动,手动复制文件可以确定哪些文件没有复制。
类简化的more或less指令
use File::Copy qw(copy cp);
my $fn='freeoa.log';
copy($fn,\*STDOUT);
参考来源:
File::Copy