epubjs
Version:
Render ePub documents in the browser, across many devices
232 lines (225 loc) • 33.1 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Data Compression</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Data Compression"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-12-SECT-4"/>Data Compression</h1></div></div></div><p>The <a id="I_indexterm12_id760639" class="indexterm"/><code class="literal">java.util.zip</code> package
contains classes you can use for data compression in streams or files. The
classes in the <code class="literal">java.util.zip</code> package
support two widespread compression formats: GZIP and ZIP. In this section,
we’ll talk about how to use these classes. We’ll also present two useful
example programs that build on what you have learned in this chapter.
After that, we’ll talk about a higher-level way to work with ZIP
archives—as filesystems—introduced with Java 7.</p><div class="sect2" title="Archives and Compressed Data"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-12-SECT-4.1"/>Archives and Compressed Data</h2></div></div></div><p><a id="idx10677" class="indexterm"/> <a id="idx10689" class="indexterm"/>The <code class="literal">java.util.zip</code>
package provides two filter streams for writing compressed data. The
<a id="I_indexterm12_id760696" class="indexterm"/><code class="literal">GZIPOutputStream</code> is for
writing data in GZIP compressed format. The <a id="I_indexterm12_id760707" class="indexterm"/><code class="literal">ZIPOutputStream</code> is for
writing compressed ZIP archives, which can contain one or many files. To
write compressed data in the GZIP format, simply wrap a <code class="literal">GZIPOutputStream</code> around an underlying stream
and write to it. The following is a complete example that shows how to
compress a file using the GZIP format, but the stream could just as well
be sent over a network connection or to any other type of stream
destination. Our <code class="literal">GZip</code> example is a
command line utility that compresses a file.</p><a id="I_12_tt810"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">java.io.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">java.util.zip.*</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">GZip</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">int</code> <code class="n">sChunk</code> <code class="o">=</code> <code class="mi">8192</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code><code class="n">String</code><code class="o">[]</code> <code class="n">args</code><code class="o">)</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(</code><code class="n">args</code><code class="o">.</code><code class="na">length</code> <code class="o">!=</code> <code class="mi">1</code><code class="o">)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Usage: GZip source"</code><code class="o">);</code>
<code class="k">return</code><code class="o">;</code>
<code class="o">}</code>
<code class="c1">// create output stream</code>
<code class="n">String</code> <code class="n">zipname</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">]</code> <code class="o">+</code> <code class="s">".gz"</code><code class="o">;</code>
<code class="n">GZIPOutputStream</code> <code class="n">zipout</code><code class="o">;</code>
<code class="k">try</code> <code class="o">{</code>
<code class="n">FileOutputStream</code> <code class="n">out</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FileOutputStream</code><code class="o">(</code><code class="n">zipname</code><code class="o">);</code>
<code class="n">zipout</code> <code class="o">=</code> <code class="k">new</code> <code class="n">GZIPOutputStream</code><code class="o">(</code><code class="n">out</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Couldn't create "</code> <code class="o">+</code> <code class="n">zipname</code> <code class="o">+</code> <code class="s">"."</code><code class="o">);</code>
<code class="k">return</code><code class="o">;</code>
<code class="o">}</code>
<code class="kt">byte</code><code class="o">[]</code> <code class="n">buffer</code> <code class="o">=</code> <code class="k">new</code> <code class="kt">byte</code><code class="o">[</code><code class="n">sChunk</code><code class="o">];</code>
<code class="c1">// compress the file</code>
<code class="k">try</code> <code class="o">{</code>
<code class="n">FileInputStream</code> <code class="n">in</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FileInputStream</code><code class="o">(</code><code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">]);</code>
<code class="kt">int</code> <code class="n">length</code><code class="o">;</code>
<code class="k">while</code> <code class="o">((</code><code class="n">length</code> <code class="o">=</code> <code class="n">in</code><code class="o">.</code><code class="na">read</code><code class="o">(</code><code class="n">buffer</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="n">sChunk</code><code class="o">))</code> <code class="o">!=</code> <code class="o">-</code><code class="mi">1</code><code class="o">)</code>
<code class="n">zipout</code><code class="o">.</code><code class="na">write</code><code class="o">(</code><code class="n">buffer</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="n">length</code><code class="o">);</code>
<code class="n">in</code><code class="o">.</code><code class="na">close</code><code class="o">();</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Couldn't compress "</code> <code class="o">+</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">]</code> <code class="o">+</code> <code class="s">"."</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">try</code> <code class="o">{</code> <code class="n">zipout</code><code class="o">.</code><code class="na">close</code><code class="o">();</code> <code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>First, we check to make sure we have a command-line argument
representing a filename. We then construct a <code class="literal">GZIPOutputStream</code> wrapped around a <code class="literal">FileOutputStream</code> representing the given
filename, with the <span class="emphasis"><em>.gz</em></span> suffix appended. With this
in place, we open the source file. We read chunks of data and write them
into the <code class="literal">GZIPOutputStream</code>. Finally,
we clean up by closing our open streams.</p><div class="sect3" title="Zip archives"><div class="titlepage"><div><div><h3 class="title"><a id="id1267505"/>Zip archives</h3></div></div></div><p><a id="idx10759" class="indexterm"/>While GZIP is simple compression format for a stream or
file, a ZIP archive is a file that is actually a collection of files,
some (or all) of which may be compressed. Writing data to a ZIP
archive file is a little more involved than simply wrapping a stream,
but not difficult. Each item in the ZIP file is represented by a
<a id="I_indexterm12_id760794" class="indexterm"/><code class="literal">ZipEntry</code> object. When
writing to a <a id="I_indexterm12_id760804" class="indexterm"/><code class="literal">ZipOutputStream</code>,
you’ll need to call <a id="I_indexterm12_id760815" class="indexterm"/><code class="literal">putNextEntry()</code> before
writing the data for each item. The following example shows how to
create a <code class="literal">ZipOutputStream</code>. You’ll
notice that it starts out with a stream wrapper just like it did when
creating a <code class="literal">GZIPOutputStream</code>:</p><a id="I_12_tt811"/><pre class="programlisting"> <code class="n">ZipOutputStream</code> <code class="n">zipout</code><code class="o">;</code>
<code class="k">try</code> <code class="o">{</code>
<code class="n">FileOutputStream</code> <code class="n">out</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FileOutputStream</code><code class="o">(</code><code class="s">"archive.zip"</code><code class="o">);</code>
<code class="n">zipout</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ZipOutputStream</code><code class="o">(</code><code class="n">out</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{}</code></pre><p>Let’s say we have two files we want to write into this archive.
Before we begin writing, we need to call <code class="literal">putNextEntry()</code> to set the name of the file
within the archive and initialize the stream to the correct position
for it. Here we create a simple ZipEntry with just a file name. You
can set other ZIP format specific fields in <code class="literal">ZipEntry</code>, but most of the time, you won’t
need to bother with them.<a id="I_indexterm12_id760867" class="indexterm"/><a id="I_indexterm12_id760874" class="indexterm"/><a id="I_indexterm12_id760882" class="indexterm"/></p><a id="I_12_tt812"/><pre class="programlisting"> <code class="k">try</code> <code class="o">{</code>
<code class="n">ZipEntry</code> <code class="n">entry</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ZipEntry</code><code class="o">(</code><code class="s">"first.dat"</code><code class="o">);</code>
<code class="n">zipout</code><code class="o">.</code><code class="na">putNextEntry</code><code class="o">(</code><code class="n">entry</code><code class="o">);</code>
<code class="n">zipout</code><code class="o">.</code><code class="na">write</code><code class="o">(</code> <code class="o">...</code> <code class="o">)</code> <code class="c1">// Write data for first file</code>
<code class="n">ZipEntry</code> <code class="n">entry</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ZipEntry</code><code class="o">(</code><code class="s">"second.dat"</code><code class="o">);</code>
<code class="n">zipout</code><code class="o">.</code><code class="na">putNextEntry</code><code class="o">(</code><code class="n">entry</code><code class="o">);</code>
<code class="n">zipout</code><code class="o">.</code><code class="na">write</code><code class="o">(</code> <code class="o">...</code> <code class="o">)</code> <code class="c1">// Write data for second file</code>
<code class="o">.</code> <code class="o">.</code> <code class="o">.</code>
<code class="n">zipout</code><code class="o">.</code><code class="na">close</code><code class="o">();</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{}</code></pre></div></div><div class="sect2" title="Decompressing Data"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-12-SECT-4.2"/>Decompressing Data</h2></div></div></div><p><a id="idx10690" class="indexterm"/> <a id="idx10705" class="indexterm"/>To decompress data in the GZIP format, simply wrap a
<a id="I_indexterm12_id760936" class="indexterm"/><code class="literal">GZIPInputStream</code> around
an underlying <code class="literal">FileInputStream</code> and
read from it. The following example complements our earlier <code class="literal">GZip</code> example and shows how to decompress a
GZIP file:</p><a id="I_12_tt813"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">java.io.*</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">java.util.zip.*</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">GUnzip</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">int</code> <code class="n">sChunk</code> <code class="o">=</code> <code class="mi">8192</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code><code class="n">String</code><code class="o">[]</code> <code class="n">args</code><code class="o">)</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(</code><code class="n">args</code><code class="o">.</code><code class="na">length</code> <code class="o">!=</code> <code class="mi">1</code><code class="o">)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Usage: GUnzip source"</code><code class="o">);</code>
<code class="k">return</code><code class="o">;</code>
<code class="o">}</code>
<code class="c1">// create input stream</code>
<code class="n">String</code> <code class="n">zipname</code><code class="o">,</code> <code class="n">source</code><code class="o">;</code>
<code class="k">if</code> <code class="o">(</code><code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">].</code><code class="na">endsWith</code><code class="o">(</code><code class="s">".gz"</code><code class="o">))</code> <code class="o">{</code>
<code class="n">zipname</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">];</code>
<code class="n">source</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">].</code><code class="na">substring</code><code class="o">(</code><code class="mi">0</code><code class="o">,</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">].</code><code class="na">length</code><code class="o">()</code> <code class="o">-</code> <code class="mi">3</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">else</code> <code class="o">{</code>
<code class="n">zipname</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">]</code> <code class="o">+</code> <code class="s">".gz"</code><code class="o">;</code>
<code class="n">source</code> <code class="o">=</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">];</code>
<code class="o">}</code>
<code class="n">GZIPInputStream</code> <code class="n">zipin</code><code class="o">;</code>
<code class="k">try</code> <code class="o">{</code>
<code class="n">FileInputStream</code> <code class="n">in</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FileInputStream</code><code class="o">(</code><code class="n">zipname</code><code class="o">);</code>
<code class="n">zipin</code> <code class="o">=</code> <code class="k">new</code> <code class="n">GZIPInputStream</code><code class="o">(</code><code class="n">in</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Couldn't open "</code> <code class="o">+</code> <code class="n">zipname</code> <code class="o">+</code> <code class="s">"."</code><code class="o">);</code>
<code class="k">return</code><code class="o">;</code>
<code class="o">}</code>
<code class="kt">byte</code><code class="o">[]</code> <code class="n">buffer</code> <code class="o">=</code> <code class="k">new</code> <code class="kt">byte</code><code class="o">[</code><code class="n">sChunk</code><code class="o">];</code>
<code class="c1">// decompress the file</code>
<code class="k">try</code> <code class="o">{</code>
<code class="n">FileOutputStream</code> <code class="n">out</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FileOutputStream</code><code class="o">(</code><code class="n">source</code><code class="o">);</code>
<code class="kt">int</code> <code class="n">length</code><code class="o">;</code>
<code class="k">while</code> <code class="o">((</code><code class="n">length</code> <code class="o">=</code> <code class="n">zipin</code><code class="o">.</code><code class="na">read</code><code class="o">(</code><code class="n">buffer</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="n">sChunk</code><code class="o">))</code> <code class="o">!=</code> <code class="o">-</code><code class="mi">1</code><code class="o">)</code>
<code class="n">out</code><code class="o">.</code><code class="na">write</code><code class="o">(</code><code class="n">buffer</code><code class="o">,</code> <code class="mi">0</code><code class="o">,</code> <code class="n">length</code><code class="o">);</code>
<code class="n">out</code><code class="o">.</code><code class="na">close</code><code class="o">();</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Couldn't decompress "</code> <code class="o">+</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">]</code> <code class="o">+</code> <code class="s">"."</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">try</code> <code class="o">{</code> <code class="n">zipin</code><code class="o">.</code><code class="na">close</code><code class="o">();</code> <code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>First, we check to make sure we have a command-line argument
representing a filename. If the argument ends with
<span class="emphasis"><em>.gz</em></span>, we figure out what the filename for the
uncompressed file should be. Otherwise, we use the given argument and
assume the compressed file has the <a id="I_indexterm12_id760986" class="indexterm"/><span class="emphasis"><em>.gz</em></span> suffix. Then we construct a
<code class="literal">GZIPInputStream</code> wrapped around a
<code class="literal">FileInputStream</code> that represents the
compressed file. With this in place, we open the target file. We read
chunks of data from the <code class="literal">GZIPInputStream</code> and write them into the target
file. Finally, we clean up by closing our open streams.</p><p>Reading a ZIP archive is also the mirror of writing. When reading
from a <a id="I_indexterm12_id761018" class="indexterm"/><code class="literal">ZipInputStream</code>, you
should call <a id="I_indexterm12_id761028" class="indexterm"/><code class="literal">getNextEntry()</code> before
reading each item. When <code class="literal">getNextEntry()</code> returns <code class="literal">null</code>, there are no more items to read. The
following example shows how to create a <code class="literal">ZipInputStream</code>:</p><a id="I_12_tt814"/><pre class="programlisting"> <code class="n">ZipInputStream</code> <code class="n">zipin</code><code class="o">;</code>
<code class="k">try</code> <code class="o">{</code>
<code class="n">FileInputStream</code> <code class="n">in</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FileInputStream</code><code class="o">(</code><code class="s">"archive.zip"</code><code class="o">);</code>
<code class="n">zipin</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ZipInputStream</code><code class="o">(</code><code class="n">in</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{}</code></pre><p>Suppose we want to read two files from this archive. Before we
begin reading, we need to call <code class="literal">getNextEntry()</code>. At the very least, the entry
gives us a name of the item we are reading from the archive:</p><a id="I_12_tt815"/><pre class="programlisting"> <code class="k">try</code> <code class="o">{</code>
<code class="n">ZipEntry</code> <code class="n">first</code> <code class="o">=</code> <code class="n">zipin</code><code class="o">.</code><code class="na">getNextEntry</code><code class="o">();</code>
<code class="n">zipin</code><code class="o">.</code><code class="na">read</code><code class="o">(</code> <code class="o">...</code> <code class="o">)</code> <code class="c1">// Read the file data</code>
<code class="o">}</code> <code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{}</code></pre><p>Now, you can read the contents of the first item in the archive.
When you <span><span>come to</span> the</span> end of the item,
the <code class="literal">read()</code> method returns <code class="literal">-1</code>. At this point, you can call <code class="literal">getNext</code><code class="literal">Entry()</code> again to read the
second item from the archive. If you call <code class="literal">getNextEntry()</code> and it returns <code class="literal">null</code>, there are no more items and you have
reached the end of the archive.<a id="I_indexterm12_id761129" class="indexterm"/><a id="I_indexterm12_id761136" class="indexterm"/></p></div><div class="sect2" title="Zip Archive As a Filesystem"><div class="titlepage"><div><div><h2 class="title"><a id="id718623"/>Zip Archive As a Filesystem</h2></div></div></div><p><a id="idx10691" class="indexterm"/> <a id="idx10706" class="indexterm"/>One of the benefits of the new <code class="literal">java.nio.file</code> package introduce with Java 7 is
the ability to implement custom filesystems in Java. (We talked about
the File API for the NIO file package earlier in this chapter and we’ll
return to the more general NIO facilities in the next section.) Java 7
ships with one such custom filesystem implementation bundled within it:
the Zip Filesystem Provider.<sup>[<a id="id718891" href="#ftn.id718891" class="footnote">35</a>]</sup> Using the Zip Filesystem Provider, we can open a ZIP
archive and treat it like a filesystem: reading, writing, copying, and
renaming files using all of the standard <code class="literal">java.nio.file</code> APIs, except that all of these
operations happen inside the ZIP archive file instead of on the host
computer filesystem (as you might otherwise expect).</p><p>The key to making this possible is that the NIO File API starts
with a <code class="literal">FileSystem</code> abstraction that
serves as a factory for <code class="literal">Path</code> objects.
In our previous discussion of the NIO File API we always simply asked
for the default filesystem using <code class="literal">Filesystems.getDefault()</code>. This time, we are
going to target a particular custom filesystem type and destination by
constructing a special URI for our ZIP archive. (As we’ll discuss in the
networking chapters, a URI is kind of like a URL except that it can be
more abstract).</p><a id="I_programlisting12_id761231"/><pre class="programlisting"> <code class="c1">// Construct the URI pointing to the ZIP archive</code>
<code class="n">URI</code> <code class="n">zipURI</code> <code class="o">=</code> <code class="n">URI</code><code class="o">.</code><code class="na">create</code><code class="o">(</code><code class="s">"jar:file:/Users/pat/tmp/MyArchive.zip"</code><code class="o">);</code>
<code class="c1">// Open or create it and write a file</code>
<code class="n">Map</code><code class="o"><</code><code class="n">String</code><code class="o">,</code> <code class="n">String</code><code class="o">></code> <code class="n">env</code> <code class="o">=</code> <code class="k">new</code> <code class="n">HashMap</code><code class="o"><>();</code>
<code class="n">env</code><code class="o">.</code><code class="na">put</code><code class="o">(</code><code class="s">"create"</code><code class="o">,</code> <code class="s">"true"</code><code class="o">);</code>
<code class="k">try</code> <code class="o">(</code> <code class="n">FileSystem</code> <code class="n">zipfs</code> <code class="o">=</code> <code class="n">FileSystems</code><code class="o">.</code><code class="na">newFileSystem</code><code class="o">(</code> <code class="n">zipURI</code><code class="o">,</code> <code class="n">env</code> <code class="o">)</code> <code class="o">)</code>
<code class="o">{</code>
<code class="n">Path</code> <code class="n">path</code> <code class="o">=</code> <code class="n">zipfs</code><code class="o">.</code><code class="na">getPath</code><code class="o">(</code><code class="s">"/README.txt"</code><code class="o">);</code>
<code class="n">OutputStream</code> <code class="n">out</code> <code class="o">=</code> <code class="n">Files</code><code class="o">.</code><code class="na">newOutputStream</code><code class="o">(</code> <code class="n">path</code> <code class="o">);</code>
<code class="k">try</code> <code class="o">(</code> <code class="n">PrintWriter</code> <code class="n">pw</code> <code class="o">=</code> <code class="k">new</code> <code class="n">PrintWriter</code><code class="o">(</code>
<code class="k">new</code> <code class="nf">OutputStreamWriter</code><code class="o">(</code> <code class="n">out</code> <code class="o">)</code> <code class="o">)</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">pw</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Hello World!"</code><code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>In this snippet, we constructed a URI for our ZIP archive using
the <code class="literal">URI</code><code class="literal">create()</code> method and the special
<span class="emphasis"><em>jar:file:</em></span> prefix. (The Java JAR format is really
just the ZIP format with some additional conventions.) We then used that
URI with the <code class="literal">Filesystems
newFileSystem()</code> method to create the right kind of filesystem
reference for us. The <code class="literal">FileSystem</code> it
returns will perform all of its operations on entries within the ZIP,
but otherwise will behave just like we’ve seen previously. The other
argument to the <a id="I_indexterm12_id761283" class="indexterm"/><code class="literal">newFileSystem()</code> method
is a <code class="literal">Map</code> containing string properties
that are specific to the provider. In this case, we pass in the value
“create” as “true,” indicating that we want the ZIP filesystem provider
to create the archive if it does not already exist. In order to know
what properties can be passed, you’ll have to consult the documentation
for the particular filesystem provider.</p><p>In our preceding snippet, we then create a <code class="literal">Path</code> for a file
<span class="emphasis"><em>/README.txt</em></span> at the root folder of the filesystem
and write a string to it. Because we are using <code class="literal">try</code>-with-resources clauses to encapsulate
opening the filesystem and writing to the file, the resources will be
automatically closed for us when the operation is complete.</p><p>Other operations proceed just as with “normal” files. For example,
we can move a file by creating a path for the existing file and a path
for the new location and then using the standard <code class="literal">Files move()</code> method.<a id="I_indexterm12_id761335" class="indexterm"/><a id="I_indexterm12_id761342" class="indexterm"/></p><a id="I_programlisting12_id761350"/><pre class="programlisting"> <code class="c1">// Move the file</code>
<code class="k">try</code> <code class="o">(</code> <code class="n">FileSystem</code> <code class="n">zipfs</code> <code class="o">=</code> <code class="n">FileSystems</code><code class="o">.</code><code class="na">newFileSystem</code><code class="o">(</code> <code class="n">fsURI</code><code class="o">,</code> <code class="n">env</code> <code class="o">)</code> <code class="o">)</code>
<code class="o">{</code>
<code class="n">Path</code> <code class="n">path</code> <code class="o">=</code> <code class="n">zipfs</code><code class="o">.</code><code class="na">getPath</code><code class="o">(</code><code class="s">"/README.txt"</code><code class="o">);</code>
<code class="n">Path</code> <code class="n">toPath</code> <code class="o">=</code> <code class="n">zipfs</code><code class="o">.</code><code class="na">getPath</code><code class="o">(</code><code class="s">"/README2.txt"</code><code class="o">);</code>
<code class="n">Files</code><code class="o">.</code><code class="na">move</code><code class="o">(</code> <code class="n">path</code><code class="o">,</code> <code class="n">toPath</code> <code class="o">);</code>
<code class="o">}</code></pre></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.id718891" href="#id718891" class="para">35</a>] </sup>The Zip Filesystem Provider is also supplied as an example
along with sample source code even though it’s unclear if Oracle
intends it to be a standard. But at the time of this writing, it is
bundled with the JDK and JRE of Java 7 on all platforms.</p></div></div></div></body></html>