您正在从Perl 5.39.5查看此文档的版本。这是Perl的开发版本。

目录

名称

Tie::File—通过Perl数组访问磁盘文件的行

简介

使用Tie::File;tie@array,'tie::File',filename或die。。。;$array[0]=“废话”;#文件的第一行现在是“废话”#(行号从0开始)打印$array[42];#文件的显示行43$n_recs=@array;#档案里有多少记录?$#数组-=2;#从末尾剪下两张唱片for(@array){s/PERL/PERL/g;#在文件中的所有位置用PERL替换PERL}#这些就像常规的推、弹出、取消移动、移动和拼接#除了他们以您期望的方式修改文件之外push@array,新记录。。。;我的$r1=pop@array;unshift@array,新记录。。。;我的$r2=shift@array;@old_recs=splice@array,3,7,新记录。。。;解开@array;#全部完成

描述

领带::文件将常规文本文件表示为Perl数组。数组中的每个元素都对应于文件中的一条记录。文件的第一行是数组的元素0;第二行是元素1,依此类推。

文件是加载到内存中,所以即使是巨大的文件也可以使用。

对数组的更改会立即反映在文件中。

懒惰的人和初学者现在可能会停止阅读手册。

记录

什么是“记录”?默认情况下,其含义与<...>运算符:这是一个以结尾的字符串$/,这可能是“\n”.(小异常:在DOS和Win32系统上,“记录”是以“\r\n”.)您可以通过提供记录中的选项领带呼叫:

tie@array,'tie::File',$File,recsep=>'es';

这表示记录由字符串分隔。如果文件包含以下数据:

诅咒这些讨厌的苍蝇!\n个

然后@阵列看起来有四个要素:

“诅咒”“e p”“ky-fli”“!\n”

不允许将未定义的值用作记录分隔符。Perl的特殊“段落模式”语义(a la$/ = "")未仿真。

从绑定数组读取的记录末尾没有记录分隔符字符串;这是为了允许

$数组[17].=“额外”;

按预期工作。

(请参见“自动转换器”,见下文。)存储在数组中的记录在写入文件之前将附加记录分隔符字符串(如果它们还没有)。例如,如果记录分隔符字符串是“\n”,则以下两行执行完全相同的操作:

$array[17]=“樱桃派”;$array[17]=“樱桃派\n”;

结果是,文件第17行的内容将被替换为“Cherry pie”;换行符将第17行与第18行分隔开。这意味着此代码将不执行任何操作:

chomp$array[17];

因为巧克力ed值将在写回文件时重新附加分隔符。无法创建缺少尾部记录分隔符字符串的文件。

插入符合以下条件的记录包含此模块不支持记录分隔符字符串。它可能会产生一个合理的结果,但这个结果在未来的版本中可能会有所改变。使用“splice”插入记录或将一条记录替换为多条记录。

自动测深仪

通常,数组元素会删除记录分隔符,因此如果文件包含文本

黄金乳香没药

绑定数组将包含(“金”、“乳香”、“没药”)。如果您设置自动测深仪如果值为false,则不会删除记录分隔符。如果上面的文件与

tie@givents,“tie::File”,$givents、autochomp=>0;

然后是数组@礼物似乎包含(“黄金”、“乳香”、“没药”)、或(在Win32系统上)(“黄金”,“乳香”,“没药”).

模式

通常,指定的文件将被打开以进行读写访问,如果不存在,则将创建该文件。(即旗帜O_RDWR|O_CREAT(_RDWR)在中提供打开呼叫)如果要更改此设置,可以在模式选项。请参见Fcntl公司获取可用标志的列表。例如:

#打开文件(如果存在),但如果不存在则失败使用Fcntl“O_RDWR”;tie@array,'tie::File',$File,mode=>O_RDWR;#如果文件不存在,则创建该文件使用Fcntl'O_RDWR','O_CREAT';tie@array,'tie::File',$File,mode=>O_RDWR | O_CREAT;#以只读模式打开现有文件使用Fcntl“O_RDONLY”;tie@array,'tie::File',$File,mode=>O_RDONLY;

不支持以只读或追加模式打开数据文件。

记忆

这是内存量的上限领带::文件将在管理文件时随时使用。这用于两件事:管理读缓存和管理延迟写入缓冲区.

从文件中读入的记录被缓存,以避免重复地重新读取它们。如果将同一记录读取两次,第一次将其存储在内存中,第二次将从读缓存。读缓存中的数据量不会超过指定的值记忆.如果领带::文件想要缓存一条新记录,但读缓存已满,它将通过使读缓存中最近访问过的记录过期来腾出空间。

默认内存限制为2Mib。您可以通过提供记忆选项。参数是所需的缓存大小,以字节为单位。

#我有很多内存,所以使用大缓存来加快访问速度tie@array,'tie::File',$File,memory=>20_000_000;

将内存限制设置为0将禁止缓存;每次检查记录时,都会从磁盘中提取记录。

这个记忆值不是所用内存的绝对或精确限制。领带::文件除了读缓存和延迟写缓冲区之外,对象还包含一些结构,这些结构的大小不受影响记忆.

缓存本身会为每个缓存的记录消耗大约310个字节,因此,如果您的文件有许多短记录,您可能需要降低缓存内存限制,否则缓存开销可能会超过缓存数据的大小。

dw_size(数据_大小)

(这是一项高级功能。第一次阅读时跳过本节。)

如果使用延迟写入(请参阅“延迟写入”,如下所示),则写入数组的数据不会直接写入文件;相反,它将保存在延迟写入缓冲区稍后写出。延迟写入缓冲区中的数据也会根据使用记忆选项。

您可以设置dw_size(数据_大小)选项来限制可以保存在延迟写入缓冲区中的数据量。此限制不能超过总内存限制。例如,如果您设置dw_size(数据_大小)至1000和记忆到2500,这意味着将保存不超过1000个字节的延迟写入。读缓存的可用空间会有所不同,但它将始终至少为1500字节(如果延迟写入缓冲区已满),并且可能会增长到2500字节(如果推迟写入缓冲区为空)

如果您没有指定dw_size(数据_大小),默认为整个内存限制。

选项格式

-模式是的同义词模式.-记录是的同义词记录.-存储器是的同义词记忆你明白了。

公共方法

这个领带调用返回一个对象,比如0美元。你可以打电话

$rec=$o->FETCH($n);$o->STORE($n,$rec);

在第行提取或存储记录n美元分别为;与其他绑定数组方法类似。(请参见珍珠岩详细信息。)您还可以对此对象调用以下方法:

一大群

$o->flock(模式)

将锁定绑定文件。MODE(模式)与Perl内置的第二个参数的含义相同一大群功能;例如锁定_SHLOCK_EX |锁_NB.(这些常数由使用Fcntl“:羊群”声明。)

MODE(模式)可选;默认值为锁定_执行.

领带::文件维护文件中每个记录的字节偏移量的内部表。

当您使用一大群锁定文件,领带::文件假设读缓存不再可信,因为自上次读取文件以来,另一个进程可能已经修改了该文件。因此,成功呼叫一大群丢弃读缓存和内部记录偏移量表的内容。

领带::文件承诺以下操作顺序是安全的:

my$o=tie@array,“tie::File”,$filename;$o->羊群;

特别地,领带::文件领带呼叫。(例外:使用模式=>O_TRUNC当然,会在领带呼叫。如果要安全地执行此操作,请在不使用O_TRUNC(_TRUNC),锁定文件,然后使用@数组=().)

解锁文件的最佳方法是丢弃对象并解开数组。在不解除文件锁定的情况下解除文件锁定可能是不安全的,因为如果这样做,对象中的更改可能仍然是未写入的。这就是为什么没有解锁的捷径。如果你真的想过早解锁文件,你知道该怎么做;如果你不知道该做什么,那就不要做。

所有关于文件锁定的常见警告都适用于此。特别要注意,Perl中的文件锁定是咨询的,这意味着持有锁不会阻止其他人读取、写入或擦除文件;这只会防止他们同时获得另一个锁。锁类似于绿色交通灯:如果你有一个绿灯,那并不能阻止从另一个方向过来的白痴从侧面撞到你;它只是向你保证,这个白痴不会同时也有绿灯。

自动测深仪

我的$old_value=$o->autochomp(0);#禁用autochomp选项我的$old_value=$o->autochomp(1);#启用自动检测选项我的$ac=$o->autochomp();#恢复电流值

请参见“自动转换器”,如上所述。

推迟,脸红,丢弃,以及自动防御

请参见“延迟写入”,如下所示。

抵消

$off=$o->偏移量($n);

此方法返回n美元文件中的第条记录。如果没有这样的记录,则返回未定义的值。

绑定到已打开的文件句柄

如果美元每小时是文件句柄,例如由IO::文件或者其中一个IO(输入输出)模块,您可以使用:

tie@array,'tie::File',$fh。。。;

同样,如果你打开那个把手FH公司有规律的打开系统打开,您可以使用:

tie@array,'tie::File',\*FH。。。;

以只读方式打开的句柄将不起作用。只要您不尝试修改数组,以只读方式开启的句柄将起作用。句柄必须连接到可查找的数据源——这意味着没有管道或套接字。如果领带::文件可以检测到您提供了一个无法识别的句柄领带调用将引发异常。(在Unix系统上,它可以检测到这一点。)

请注意,Tie::File将只关闭它在内部打开的所有文件句柄。如果如上所述传递给它一个文件句柄,则您“拥有”该文件句柄,并负责在解开@数组后将其关闭。

并列::文件调用双模在内部打开的文件句柄上,但不在用户传入的文件句柄中。为了保持一致性,特别是在跨平台使用绑定文件的情况下,您可能希望调用双模在绑定文件之前在文件句柄上。

延期写入

(这是一项高级功能。第一次阅读时跳过本节。)

通常,修改领带::文件数组立即写入底层文件。每个作业都像$a[3]=。。。根据需要重写尽可能多的文件;通常,从第3行到末尾的所有内容都需要重写。这是最简单、最透明的行为。即使对于大型文件,性能也相当好。

然而,在某些情况下,这种行为可能过于缓慢。例如,假设您有一个百万记录文件,并且您希望:

for(@FILE){$_ = "> $_";}

第一次循环时,您将重写整个文件,从第0行到末尾。第二次循环时,您将从第1行到末尾重写整个文件。第三次循环时,您将把整个文件从第2行重写到末尾。等等。

如果这种情况下的表现不可接受,您可以推迟实际写作,然后立即全部完成。对于大文件,以下循环将执行得更好:

(并列@a)->推迟;对于(@a){$_ = "> $_";}(捆扎@a)->齐平;

如果领带::文件的内存限制足够大,所有写操作都将在内存中完成。然后,当你打电话时->冲洗,整个文件将在一次传递中被重写。

(实际上,前面的讨论有点像小谎。在这种常见情况下,您不需要启用延迟写入来获得良好的性能,因为领带::文件将自动为您执行此操作,除非您明确告知不要执行此操作。请参阅“自动延迟”,见下文。)

打电话->冲洗将数组返回到立即写入模式。如果您希望放弃延迟写入,可以调用->丢弃而不是->冲洗请注意,在某些情况下,一些数据已经写入,现在已经太晚了->丢弃放弃所有更改。支持->丢弃可能在未来版本的领带::文件.

延迟写入缓存在内存中,上限由dw_size(数据_大小)选项(见上文)。如果延迟写入缓冲区已满,并且您尝试写入更多延迟数据,则缓冲区将被刷新。所有缓冲的数据都将立即写入,缓冲区将被清空,现在空的空间将用于未来的延迟写入。

如果延迟写入缓冲区尚未满,但缓冲区和读缓存的总大小将超过记忆限制,最旧的记录将从读缓存中过期,直到总大小低于限制。

,流行音乐,转移,取消移位,以及剪接无法延迟。当您执行其中一个操作时,任何延迟的数据都会写入文件,并立即执行该操作。在未来版本中,这可能会发生变化。

如果在启用延迟写入的情况下调整数组大小,则会立即调整文件大小,但不会写入延迟记录。这有一个令人惊讶的结果:@a=(…)立即擦除文件,但延迟写入实际数据。这可能是一个错误。如果它是一个错误,将在未来版本中修复。

自动延迟

领带::文件尝试猜测延迟写什么时候可能有用,并自动打开和关闭。

对于(@a){$_ = "> $_";}

在这个例子中,只有前两个作业会立即完成;在此之后,对文件的所有更改都将延迟到用户指定的内存限制。

通常,您应该可以忽略这一点,只使用模块而不考虑延迟。但是,特殊应用程序可能需要对哪些写入被延迟进行精细控制,或者可能需要立即执行所有写入。要禁用自动防御功能,请使用

(绑定@o)->自动防御(0);

tie@array,'tie::File',$File,autodefer=>0;

同样,->自动导向(1)重新启用自动防御,以及->自动延迟()恢复自动防御设置的当前值。

对文件的并发访问

如果希望从多个进程同时访问同一文件,则缓存和延迟写入是不合适的。此模块内部执行的其他优化也与并发访问不兼容。此模块的未来版本将支持并发=>1启用安全并发访问的选项。

本文档的早期版本建议使用内存=>0以实现安全的并发访问。这是错误的。在0.96之前,文件将不支持安全并发访问。

CAVEATS(洞穴)

(这是拉丁文中的“警告”。)

子分类

这个版本绝对不承诺任何关于内部的内容,这些内容可能会发生更改,恕不另行通知。该模块的未来版本将具有定义良好且稳定的子类化API。

关于DB_文件?

人们有时会指出DB_文件会做类似的事情,并询问原因领带::文件模块是必需的。

您可能会喜欢以下几个原因领带::文件。列表位于http://perl.plover.com/TieFile/why-not-DB_File文件.

作者

马克·杰森·多明斯

要联系作者,请发送电子邮件至:mjd-perl-tiefile+@plover.com

要在发布此模块的新版本时接收公告,请发送空白电子邮件至mjd-perl-tiefile-subscribe@plover.com.

本模块的最新版本,包括文档和任何重要新闻,将在

http://perl.plover.com/TieFile/

许可证

领带::文件0.96版版权所有(C)2003 Mark Jason Dominus。

这个库是自由软件;您可以按照与Perl本身相同的术语重新分发和/或修改它。

这些术语是您选择的(1)Perl Artistic许可证,或(2)自由软件基金会发布的GNU通用公共许可证的第2版,或(3)GNU通用公用许可证的任何更高版本。

本库的发行是为了希望它有用,但没有任何保证;甚至没有对适销性或特定用途适用性的隐含保证。有关更多详细信息,请参阅GNU通用公共许可证。

您应该已经收到GNU通用公共许可证的副本以及此库程序;它应该在文件中复制如果没有,请写信给美国马萨诸塞州波士顿富兰克林街51号五楼自由软件基金会,邮编:02110-1301

有关许可查询,请联系作者:

马克·杰森·多明斯华诺克南街255号。宾夕法尼亚州费城,邮编:19107

担保

领带::文件版本0.98附带绝对无担保。有关详细信息,请参阅许可证。

谢谢

非常感谢Jarkko Hietaniemi,感谢他在我还没有写这本书的时候就同意把它放在核心位置,感谢他总体上的帮助、支持和胜任。(通常规则是“任选一个”。)同样要感谢阿比吉特·梅隆森(Abhijit Menon-Sen)所做的一切。

特别感谢Craig Berry和Peter Prymmer(负责VMS可移植性帮助)、Randy Kobes(负责Win32可移植性协助)、Clinton Pierce和Autrijus Tang(负责超出职责范围的英勇的11小时Win32测试)、Michael G Schwern(负责测试建议)和其他CPAN测试人员(通常用于测试)。

特别感谢Tels提出了一些速度和内存优化建议。

更多感谢:爱德华·阿维斯/马蒂亚·巴本/汤姆·克里斯蒂安森/杰里特·哈斯/古鲁萨米·萨拉西/贾科·希塔尼米(再次)/尼古拉·克内泽维奇/约翰·科米内茨/尼克·英·西蒙斯/塔西洛·冯·帕塞瓦尔/H.迪特尔·皮尔西/斯拉文·雷齐克/埃里克·鲁德/彼得·斯科特/彼得·索姆/奥特里朱斯·唐(再次)/Tels(再次)/Juerd Waalboer/托德·里纳尔多

TODO公司

更多测试。(我还没想到的东西。)

段落模式?

固定长度模式。Leave-blanks模式。

也许是自动锁定模式?

对于该模块的许多常见用途,读缓存是一项责任。例如,插入单个记录或扫描一次文件的程序的缓存命中率为零。这意味着一个主要的优化:缓存最初应该被禁用。这里有一种混合方法:最初,缓存是禁用的,但缓存代码维护了有关启用缓存后命中率会有多高的统计信息。当它看到命中率足够高时,它就会启用自己。此代码中的STAT注释是此实现的开始。

用fcntl()锁定记录?然后,该模块可能支持撤消日志并获取实际事务。那将是一场多么精彩的巡回演出。

跟踪缓存的最高记录。这将允许行中读取更快地跳过缓存查找(如果从1..N开始读取时缓存为空,则最后缓存的值始终为N-1)。

更多测试。