📄 ch11_14.htm
字号:
<HTML><HEAD><TITLE>Recipe 11.13. Storing Data Structures to Disk (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:40:53Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch11_01.htm"TITLE="11. References and Records"><LINKREL="prev"HREF="ch11_13.htm"TITLE="11.12. Copying Data Structures"><LINKREL="next"HREF="ch11_15.htm"TITLE="11.14. Transparently Persistent Data Structures"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch11_13.htm"TITLE="11.12. Copying Data Structures"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 11.12. Copying Data Structures"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch11_01.htm"TITLE="11. References and Records"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch11_15.htm"TITLE="11.14. Transparently Persistent Data Structures"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 11.14. Transparently Persistent Data Structures"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch11-38864">11.13. Storing Data Structures to Disk</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch11-pgfId-1342">Problem<ACLASS="indexterm"NAME="ch11-idx-1000004872-0"></A><ACLASS="indexterm"NAME="ch11-idx-1000004872-1"></A><ACLASS="indexterm"NAME="ch11-idx-1000004872-2"></A></A></H3><PCLASS="para">You want to save your large, complex data structure to disk so you don't have to build it up each time your program runs.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch11-pgfId-1348">Solution</A></H3><PCLASS="para">Use the CPAN module Storable's <CODECLASS="literal">store</CODE> and <CODECLASS="literal">retrieve</CODE> functions:</P><PRECLASS="programlisting">use Storable; store(\%hash, "filename");# later on... $href = retrieve("filename"); # by ref%hash = %{ retrieve("filename") }; # direct to hash</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch11-pgfId-1366">Discussion</A></H3><PCLASS="para">The Storable module uses C functions and a binary format to walk Perl's internal data structures and lay out its data. It's more efficient than a pure Perl and string-based approach, but it's also more fragile.</P><PCLASS="para"><CODECLASS="literal">The</CODE> <CODECLASS="literal">store</CODE> and <CODECLASS="literal">retrieve</CODE> functions expect binary data using the machine's own byte-ordering. This means files created with these functions cannot be shared across different architectures. <CODECLASS="literal">nstore</CODE><ACLASS="indexterm"NAME="ch11-idx-1000004878-0"></A> does the same job <CODECLASS="literal">store</CODE> does, but keeps data in canonical (network) byte order, at a slight speed cost:</P><PRECLASS="programlisting">use Storable qw(nstore); nstore(\%hash, "filename"); # later ... $href = retrieve("filename");</PRE><PCLASS="para">No matter whether <CODECLASS="literal">store</CODE> or <CODECLASS="literal">nstore</CODE> was used, you need to call the same <CODECLASS="literal">retrieve</CODE> routine to restore the objects in memory. The producer must commit to portability, but the consumer doesn't have to. Code needs only to be changed in one place when the producer changes their mind and the code thus offers a consistent interface on the consumer side, who does not need to know or care.</P><PCLASS="para">The <CODECLASS="literal">store</CODE> and <CODECLASS="literal">nstore</CODE> functions don't lock any of the files they work on. If you're worried about concurrent access, open the file yourself, lock it using <ACLASS="xref"HREF="ch07_12.htm"TITLE="Locking a File">Recipe 7.11</A>, and then use <CODECLASS="literal">store_fd</CODE> or its slower but machine-independent version <CODECLASS="literal">nstore_fd</CODE>.</P><PCLASS="para">Here's code to save a hash to a file, with locking. We don't open with the <CODECLASS="literal">O_TRUNC</CODE> flag because we have to wait to get the lock before we can clobber the file.</P><PRECLASS="programlisting">use Storable qw(nstore_fd);use Fcntl qw(:DEFAULT :flock);sysopen(DF, "/tmp/datafile", O_RDWR|O_CREAT, 0666) or die "can't open /tmp/datafile: $!";flock(DF, LOCK_EX) or die "can't lock /tmp/datafile: $!";nstore_fd(\%hash, *DF) or die "can't store hash\n";truncate(DF, tell(DF));close(DF);</PRE><PCLASS="para">Here's code to restore that hash from a file, with locking:</P><PRECLASS="programlisting">use Storable;use Fcntl qw(:DEFAULT :flock);open(DF, "< /tmp/datafile") or die "can't open /tmp/datafile: $!";flock(DF, LOCK_SH) or die "can't lock /tmp/datafile: $!";$href = retrieve(*DF);close(DF);</PRE><PCLASS="para">With care, you can pass large data objects efficiently between processes with this strategy, since a filehandle connected to a pipe or socket is still a byte stream, just like a plain file.</P><PCLASS="para">Unlike the various DBM bindings, Storable does not restrict you to using only hashes (or arrays, with DB_File). Arbitrary data structures, including objects, can be stored to disk. The whole structure must be read in or written out in its entirety.<ACLASS="indexterm"NAME="ch11-idx-1000004874-0"></A><ACLASS="indexterm"NAME="ch11-idx-1000004874-1"></A><ACLASS="indexterm"NAME="ch11-idx-1000004874-2"></A><ACLASS="indexterm"NAME="ch11-idx-1000004874-3"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch11-pgfId-1430">See Also</A></H3><PCLASS="para">The section on <ACLASS="olink"HREF="../advprog/ch13_02.htm">"Remote Procedure Calls (RPC)"</A> in <ACLASS="olink"HREF="../advprog/ch13_01.htm">Chapter 13</A> of <ACLASS="citetitle"HREF="../advprog/index.htm"TITLE="Advanced Perl Programming"><CITECLASS="citetitle">Advanced Perl Programming</CITE></A>; <ACLASS="xref"HREF="ch11_15.htm"TITLE="Transparently Persistent Data Structures">Recipe 11.14</A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch11_13.htm"TITLE="11.12. Copying Data Structures"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 11.12. Copying Data Structures"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch11_15.htm"TITLE="11.14. Transparently Persistent Data Structures"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 11.14. Transparently Persistent Data Structures"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">11.12. Copying Data Structures</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">11.14. Transparently Persistent Data Structures</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -