epubjs
Version:
Render ePub documents in the browser, across many devices
323 lines (317 loc) • 67.4 kB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>File I/O</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="File I/O"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-12-SECT-2"/>File I/O</h1></div></div></div><p>In this chapter, we’re going to talk about the Java file I/O API. To
be more precise, we are going to talk about two file APIs: first, there is
the core <code class="literal">java.io</code> File I/O facility that
has been part of Java since the beginning. Then there is the “new”
<code class="literal">java.nio.file</code> API introduced in Java 7.
In general the NIO packages, which we’ll cover in detail later and which
touch upon not only files but all types of network and channel I/O, were
introduced to add advanced features that make Java more scaleable and
higher performance. However, in the case of file NIO, the new package is
also just somewhat of a “do-over” on the original API. In movie terms, you
can think of the two APIs as the “classic” and the “reboot” of the series.
The new API completely duplicates the functionality of the original, but
because the core API is so fundamental (and in some cases simpler), it is
likely that many people will prefer to keep using it. We’ll start with the
classic API centering on <code class="literal">java.io.File</code>
and later we’ll cover the new API, which centers on the analogous <code class="literal">java.nio.Path</code>.</p><p>Working with files in Java is easy, but poses some conceptual
problems. Real-world filesystems can vary widely in architecture and
implementation: think of the differences between Mac, PC, and Unix systems
when it comes to filenames. Java tries to mask some of these differences
and provide information to help an application tailor itself to the local
environment, but it leaves a lot of the details of file access
implementation dependent. We’ll talk about techniques for dealing with
this as we go.</p><p>Before we leave File I/O we’ll also show you some tools for the
special case of application “resource” files packaged with your app and
loaded via the Java classpath.</p><div class="sect2" title="The java.io.File Class"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-12-SECT-2.1"/>The java.io.File Class</h2></div></div></div><p><a id="idx10708" class="indexterm"/>The <code class="literal">java.io.File</code> class
encapsulates access to information about a file or directory. It can be
used to get attribute information about a file, list the entries in a
directory, and perform basic filesystem operations, such as removing a
file or making a directory. While the <code class="literal">File</code> object handles these “meta” operations,
it doesn’t provide the API for reading and writing file data; there are
file streams for that purpose.</p><div class="sect3" title="File constructors"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-12-SECT-2.1.1"/>File constructors</h3></div></div></div><p><a id="idx10694" class="indexterm"/> <a id="idx10697" class="indexterm"/>You can create an instance of <code class="literal">File</code> from a <code class="literal">String</code> pathname:</p><a id="I_12_tt784"/><pre class="programlisting"> <code class="n">File</code> <code class="n">fooFile</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="s">"/tmp/foo.txt"</code> <code class="o">);</code>
<code class="n">File</code> <code class="n">barDir</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="s">"/tmp/bar"</code> <code class="o">);</code></pre><p>You can also create a file with a relative path:</p><a id="I_12_tt785"/><pre class="programlisting"> <code class="n">File</code> <code class="n">f</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="s">"foo"</code> <code class="o">);</code></pre><p>In this case, Java works relative to the “current working
directory” of the Java interpreter. You can determine the current
working directory by reading the <code class="literal">user.dir</code> property in the <code class="literal">System Properties</code> list:</p><a id="I_12_tt786"/><pre class="programlisting"> <code class="n">System</code><code class="o">.</code><code class="na">getProperty</code><code class="o">(</code><code class="s">"user.dir"</code><code class="o">);</code> <code class="c1">// e.g.,"/Users/pat"</code></pre><p>An overloaded version of the <code class="literal">File</code> constructor lets you specify the
directory path and filename as separate <code class="literal">String</code> objects:</p><a id="I_12_tt787"/><pre class="programlisting"> <code class="n">File</code> <code class="n">fooFile</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="s">"/tmp"</code><code class="o">,</code> <code class="s">"foo.txt"</code> <code class="o">);</code></pre><p>With yet another variation, you can specify the directory with a
<code class="literal">File</code> object and the filename with a
<code class="literal">String</code>:</p><a id="I_12_tt788"/><pre class="programlisting"> <code class="n">File</code> <code class="n">tmpDir</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="s">"/tmp"</code> <code class="o">);</code> <code class="c1">// File for directory /tmp</code>
<code class="n">File</code> <code class="n">fooFile</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code> <code class="o">(</code> <code class="n">tmpDir</code><code class="o">,</code> <code class="s">"foo.txt"</code> <code class="o">);</code></pre><p>None of these <code class="literal">File</code>
constructors actually creates a file or directory, and it is not an
error to create a <code class="literal">File</code> object for a
nonexistent file. The <code class="literal">File</code> object
is just a handle for a file or directory whose properties you may wish
to read, write, or test. For example, you can use the <code class="literal">exists()</code> instance method to learn whether
the file or directory exists.<a id="I_indexterm12_id754469" class="indexterm"/><a id="I_indexterm12_id754476" class="indexterm"/></p></div><div class="sect3" title="Path localization"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-12-SECT-2.1.2"/>Path localization</h3></div></div></div><p><a id="idx10696" class="indexterm"/> <a id="idx10699" class="indexterm"/>One issue with working with files in Java is that
pathnames are expected to follow the conventions of the local
filesystem. Two differences are that the Windows filesystem uses
“roots” or drive letters (for example, C:) and a backslash (\) instead
of the forward slash (/) path separator that is used in other
systems.</p><p>Java tries to compensate for the differences. For example, on
Windows platforms, Java accepts paths with either forward slashes or
backslashes. (On others, however, it only accepts forward
slashes.)</p><p>Your best bet is to make sure you follow the filename
conventions of the host filesystem. If your application has a GUI that
is opening and saving files at the user’s request, you should be able
to handle that functionality with the Swing <a id="I_indexterm12_id754535" class="indexterm"/><code class="literal">JFileChooser</code> class.
This class encapsulates a graphical file-selection dialog box. The
methods of the <code class="literal">JFileChooser</code> take
care of system-dependent filename features for you.</p><p>If your application needs to deal with files on its own behalf,
however, things get a little more complicated. The <code class="literal">File</code> class contains a few <code class="literal">static</code> variables to make this task possible.
<code class="literal">File.separator</code> defines a <code class="literal">String</code> that specifies the file separator on
the local host (e.g., <code class="literal">/</code> on Unix and
Macintosh systems and <code class="literal">\</code> on Windows
systems); <a id="I_indexterm12_id754589" class="indexterm"/><code class="literal">File.separatorChar</code>
provides the same information as a <code class="literal">char</code>.</p><p>You can use this system-dependent information in several ways.
Probably the simplest way to localize pathnames is to pick a
convention that you use internally, such as the forward slash (/), and
do a <code class="literal">String</code> replace to substitute
for the localized separator character:</p><a id="I_12_tt789"/><pre class="programlisting"> <code class="c1">// we'll use forward slash as our standard</code>
<code class="n">String</code> <code class="n">path</code> <code class="o">=</code> <code class="s">"mail/2004/june/merle"</code><code class="o">;</code>
<code class="n">path</code> <code class="o">=</code> <code class="n">path</code><code class="o">.</code><code class="na">replace</code><code class="o">(</code><code class="sc">'/'</code><code class="o">,</code> <code class="n">File</code><code class="o">.</code><code class="na">separatorChar</code><code class="o">);</code>
<code class="n">File</code> <code class="n">mailbox</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="n">path</code> <code class="o">);</code></pre><p>Alternatively, you could work with the components of a pathname
and build the local pathname when you need it:</p><a id="I_12_tt790"/><pre class="programlisting"> <code class="n">String</code> <code class="o">[]</code> <code class="n">path</code> <code class="o">=</code> <code class="o">{</code> <code class="s">"mail"</code><code class="o">,</code> <code class="s">"2004"</code><code class="o">,</code> <code class="s">"june"</code><code class="o">,</code> <code class="s">"merle"</code> <code class="o">};</code>
<code class="n">StringBuffer</code> <code class="n">sb</code> <code class="o">=</code> <code class="k">new</code> <code class="n">StringBuffer</code><code class="o">(</code><code class="n">path</code><code class="o">[</code><code class="mi">0</code><code class="o">]);</code>
<code class="k">for</code> <code class="o">(</code><code class="kt">int</code> <code class="n">i</code><code class="o">=</code><code class="mi">1</code><code class="o">;</code> <code class="n">i</code><code class="o"><</code> <code class="n">path</code><code class="o">.</code><code class="na">length</code><code class="o">;</code> <code class="n">i</code><code class="o">++)</code>
<code class="n">sb</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="n">File</code><code class="o">.</code><code class="na">separator</code> <code class="o">+</code> <code class="n">path</code><code class="o">[</code><code class="n">i</code><code class="o">]</code> <code class="o">);</code>
<code class="n">File</code> <code class="n">mailbox</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="n">sb</code><code class="o">.</code><code class="na">toString</code><code class="o">()</code> <code class="o">);</code></pre><div class="note" title="Note"><h3 class="title">Note</h3><p>One thing to remember is that Java interprets a literal
backslash character (<code class="literal">\</code>) in source
code as an escape character when used in a <code class="literal">String</code>. To get a backslash in a <code class="literal">String</code>, you have to use <a id="I_indexterm12_id754666" class="indexterm"/><a id="I_indexterm12_id754671" class="indexterm"/><code class="literal">\\</code>.</p></div><p>To grapple with the issue of filesystems with multiple “roots”
(for example, <code class="literal">C:\</code> on Windows), the
<code class="literal">File</code> class provides the static
method <a id="I_indexterm12_id754696" class="indexterm"/><code class="literal">listRoots()</code>, which
returns an array of <code class="literal">File</code> objects
corresponding to the filesystem root directories. Again, in a GUI
application, a graphical file chooser dialog shields you from this
problem entirely.<a id="I_indexterm12_id754714" class="indexterm"/><a id="I_indexterm12_id754721" class="indexterm"/></p></div><div class="sect3" title="File operations"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-12-SECT-2.1.3"/>File operations</h3></div></div></div><p><a id="idx10695" class="indexterm"/> <a id="idx10698" class="indexterm"/>Once we have a <code class="literal">File</code>
object, we can use it to ask for information about and perform
standard operations on the file or directory it represents. A number
of methods let us ask questions about the <code class="literal">File</code>. For example, <a id="I_indexterm12_id754774" class="indexterm"/><code class="literal">isFile()</code> returns
<code class="literal">true</code> if the <code class="literal">File</code> represents a regular file, while
<a id="I_indexterm12_id754796" class="indexterm"/><code class="literal">isDirectory()</code> returns
<code class="literal">true</code> if it’s a directory.
<a id="I_indexterm12_id754813" class="indexterm"/><code class="literal">isAbsolute()</code>
indicates whether the <code class="literal">File</code>
encapsulates an <span class="emphasis"><em>absolute path</em></span> or
<span class="emphasis"><em>relative path</em></span> specification. An absolute path is
a system-dependent notion that means that the path doesn’t depend on
the application’s working directory or any concept of a working root
or drive (e.g., in Windows, it is a full path including the drive
letter: <em class="filename">c:\\Users\pat\foo.txt</em>).</p><p>Components of the <code class="literal">File</code>
pathname are available through the following methods: <a id="I_indexterm12_id754854" class="indexterm"/><code class="literal">getName()</code>, <a id="I_indexterm12_id754865" class="indexterm"/><code class="literal">getPath()</code>, <a id="I_indexterm12_id754876" class="indexterm"/><code class="literal">getAbsolutePath()</code>,
and <a id="I_indexterm12_id754887" class="indexterm"/><code class="literal">getParent()</code>. <code class="literal">getName()</code> returns a <code class="literal">String</code> for the filename without any
directory information. If the <code class="literal">File</code>
has an absolute path specification, <code class="literal">getAbsolutePath()</code> returns that path.
Otherwise, it returns the relative path appended to the current
working directory (attempting to make it an absolute path). <code class="literal">getParent()</code> returns the parent directory of
the file or directory.</p><p>The string returned by <code class="literal">getPath()</code> or <code class="literal">getAbsolutePath()</code> may not follow the same
case conventions as the underlying filesystem. You can retrieve the
filesystem’s own or “canonical” version of the file’s path by using
the method <code class="literal">getCanonicalPath()</code>. In
Windows, for example, you can create a <code class="literal">File</code> object whose <code class="literal">getAbsolutePath()</code> is
<span class="emphasis"><em>C:\Autoexec.bat</em></span> but whose <a id="I_indexterm12_id754964" class="indexterm"/><code class="literal">getCanonicalPath()</code> is
<span class="emphasis"><em>C:\AUTOEXEC.BAT</em></span>; both actually point to the same
file. This is useful for comparing filenames that may have been
supplied with different case conventions or for showing them to the
user.</p><p>You can get or set the modification time of a file or directory
with <a id="I_indexterm12_id754982" class="indexterm"/><code class="literal">lastModified()</code> and
<a id="I_indexterm12_id754993" class="indexterm"/><code class="literal">setLastModified()</code>
methods. The value is a <code class="literal">long</code> that
is the number of milliseconds since the <span class="emphasis"><em>epoch</em></span>
(Jan 1, 1970, 00:00:00 GMT). We can also get the size of the file in
bytes with <a id="I_indexterm12_id755014" class="indexterm"/><code class="literal">length()</code>.</p><p>Here’s a fragment of code that prints some information about a
file:</p><a id="I_12_tt791"/><pre class="programlisting"> <code class="n">File</code> <code class="n">fooFile</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code> <code class="s">"/tmp/boofa"</code> <code class="o">);</code>
<code class="n">String</code> <code class="n">type</code> <code class="o">=</code> <code class="n">fooFile</code><code class="o">.</code><code class="na">isFile</code><code class="o">()</code> <code class="o">?</code> <code class="s">"File "</code> <code class="o">:</code> <code class="s">"Directory "</code><code class="o">;</code>
<code class="n">String</code> <code class="n">name</code> <code class="o">=</code> <code class="n">fooFile</code><code class="o">.</code><code class="na">getName</code><code class="o">();</code>
<code class="kt">long</code> <code class="n">len</code> <code class="o">=</code> <code class="n">fooFile</code><code class="o">.</code><code class="na">length</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="n">type</code> <code class="o">+</code> <code class="n">name</code> <code class="o">+</code> <code class="s">", "</code> <code class="o">+</code> <code class="n">len</code> <code class="o">+</code> <code class="s">" bytes "</code> <code class="o">);</code></pre><p>If the <code class="literal">File</code> object
corresponds to a directory, we can list the files in the directory
with the <a id="I_indexterm12_id755049" class="indexterm"/><code class="literal">list()</code> method or the
<a id="I_indexterm12_id755062" class="indexterm"/><code class="literal">listFiles()</code>
method:</p><a id="I_12_tt792"/><pre class="programlisting"> <code class="n">File</code> <code class="n">tmpDir</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</code><code class="o">(</code><code class="s">"/tmp"</code> <code class="o">);</code>
<code class="n">String</code> <code class="o">[]</code> <code class="n">fileNames</code> <code class="o">=</code> <code class="n">tmpDir</code><code class="o">.</code><code class="na">list</code><code class="o">();</code>
<code class="n">File</code> <code class="o">[]</code> <code class="n">files</code> <code class="o">=</code> <code class="n">tmpDir</code><code class="o">.</code><code class="na">listFiles</code><code class="o">();</code></pre><p><code class="literal">list()</code> returns an array of
<code class="literal">String</code> objects that contains
filenames. <code class="literal">listFiles()</code> returns an
array of <code class="literal">File</code> objects. Note that in
neither case are the files guaranteed to be in any kind of order
(alphabetical, for example). You can use the Collections API to sort
strings alphabetically like so:</p><a id="I_12_tt793"/><pre class="programlisting"> <code class="n">List</code> <code class="n">list</code> <code class="o">=</code> <code class="n">Arrays</code><code class="o">.</code><code class="na">asList</code><code class="o">(</code> <code class="n">sa</code> <code class="o">);</code>
<code class="n">Collections</code><code class="o">.</code><code class="na">sort</code><code class="o">(</code><code class="n">list</code><code class="o">);</code></pre><p>If the <code class="literal">File</code> refers to a
nonexistent directory, we can create the directory with <a id="I_indexterm12_id755124" class="indexterm"/><code class="literal">mkdir()</code> or <a id="I_indexterm12_id755134" class="indexterm"/><code class="literal">mkdirs()</code>. The
<code class="literal">mkdir()</code> method creates at most a
single directory level, so any intervening directories in the path
must already exist. <code class="literal">mkdirs()</code>
creates all directory levels necessary to create the full path of the
<code class="literal">File</code> specification. In either case,
if the directory cannot be created, the method returns <code class="literal">false</code>. Use <a id="I_indexterm12_id755169" class="indexterm"/><code class="literal">renameTo()</code> to rename
a file or directory and <a id="I_indexterm12_id755180" class="indexterm"/><code class="literal">delete()</code> to delete a
file or directory.</p><p>Although we can create a directory using the <code class="literal">File</code> object, this isn’t the most common way
to create a file; that’s normally done implicitly when we intend to
write data to it with a <code class="literal">FileOutputStream</code> or <code class="literal">FileWriter</code>, as we’ll discuss in a moment.
The exception is the <a id="I_indexterm12_id755213" class="indexterm"/><code class="literal">createNewFile()</code>
method, which can be used to attempt to create a new zero-length file
at the location pointed to by the <code class="literal">File</code> object. The useful thing about this
method is that the operation is guaranteed to be “atomic” with respect
to all other file creation in the filesystem. <code class="literal">createNewFile()</code> returns a Boolean value that
tells you whether the file was created or not. This is sometimes used
as a primitive locking feature—whoever creates the file first
“wins.” (The NIO package supports true file locks, as we’ll see
later.) This is useful in combination <a id="I_indexterm12_id755248" class="indexterm"/><code class="literal">deleteOnExit()</code>, which
flags the file to be automatically removed when the Java VM exits.
This combination allows you to guard resources or make an application
that can only be run in a single instance at a time. Another file
creation method that is related to the <code class="literal">File</code> class itself is the static method
<code class="literal">createTempFile()</code>, which creates a
file in a specified location using an automatically generated unique
name. This, too, is useful in combination with <code class="literal">deleteOnExit()</code>.</p><p>The <a id="I_indexterm12_id755281" class="indexterm"/><code class="literal">toURL()</code> method
converts a file path to a <code class="literal">file:</code> URL
object. URLs are an abstraction that allows you to point to any kind
of object anywhere on the Net. Converting a <code class="literal">File</code> reference to a URL may be useful for
consistency with more general utilities that deal with URLs. See <a class="xref" href="ch14.html" title="Chapter 14. Programming for the Web">Chapter 14</a> for details. File URLs also come into
greater use with the NIO File API where they can be used to reference
new types of filesystems that are implemented directly in Java
code.</p><p><a class="xref" href="ch12s02.html#learnjava3-CHP-12-TABLE-1" title="Table 12-1. File methods">Table 12-1</a> summarizes the
methods provided by the <code class="literal">File</code>
class.</p><div class="table"><a id="learnjava3-CHP-12-TABLE-1"/><p class="title">Table 12-1. File methods</p><div class="table-contents"><table summary="File methods" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col/><col/><col/></colgroup><thead><tr><th style="text-align: left"><p>Method</p></th><th style="text-align: left"><p>Return type</p></th><th style="text-align: left"><p>Description</p></th></tr></thead><tbody><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755377" class="indexterm"/> <code class="literal">canExecute()</code>
</p></td><td style="text-align: left"><p> <code class="literal">Boolean</code> </p></td><td style="text-align: left"><p>Is the file
executable?</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755411" class="indexterm"/> <code class="literal">canRead()</code>
</p></td><td style="text-align: left"><p> <code class="literal">Boolean</code> </p></td><td style="text-align: left"><p>Is the file (or directory)
readable?</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755445" class="indexterm"/> <code class="literal">canWrite()</code>
</p></td><td style="text-align: left"><p> <code class="literal">Boolean</code> </p></td><td style="text-align: left"><p>Is the file (or directory)
writable?</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755479" class="indexterm"/> <code class="literal">createNewFile()</code> </p></td><td style="text-align: left"><p> <code class="literal">Boolean</code> </p></td><td style="text-align: left"><p>Creates a new file.</p></td></tr><tr><td style="text-align: left"><p> <code class="literal">createTempFile (String</code>
<em class="replaceable"><code>pfx</code></em>, <a id="I_indexterm12_id755522" class="indexterm"/><code class="literal">String</code><em class="replaceable"><code>sfx</code></em><code class="literal">)</code></p></td><td style="text-align: left"><p> <code class="literal">File</code> </p></td><td style="text-align: left"><p>Static method to create a new file,
with the specified prefix and suffix, in the default temp file
directory.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755561" class="indexterm"/> <code class="literal">delete()</code>
</p></td><td style="text-align: left"><p> <code class="literal">Boolean</code> </p></td><td style="text-align: left"><p>Deletes the file (or
directory).</p></td></tr><tr><td style="text-align: left"><p> <code class="literal">deleteOnExit()</code> </p></td><td style="text-align: left"><p> <code class="literal">Void</code> </p></td><td style="text-align: left"><p>When it exits, Java runtime system
deletes the file.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755622" class="indexterm"/> <code class="literal">exists()</code>
</p></td><td style="text-align: left"><p> <code class="literal">Boolean</code> </p></td><td style="text-align: left"><p>Does the file (or directory)
exist?</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755656" class="indexterm"/> <code class="literal">getAbsolutePath()</code> </p></td><td style="text-align: left"><p> <code class="literal">String</code> </p></td><td style="text-align: left"><p>Returns the absolute path of the
file (or directory).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755691" class="indexterm"/> <code class="literal">getCanonicalPath()</code> </p></td><td style="text-align: left"><p> <code class="literal">String</code> </p></td><td style="text-align: left"><p>Returns the absolute, case-correct
path of the file (or directory).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755726" class="indexterm"/> <code class="literal">getFreeSpace()</code> </p></td><td style="text-align: left"><p> <code class="literal">long</code> </p></td><td style="text-align: left"><p>Get the number of bytes of
unallocated space on the partition holding this path or 0 if
the path is invalid.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755761" class="indexterm"/> <code class="literal">getName()</code>
</p></td><td style="text-align: left"><p> <code class="literal">String</code> </p></td><td style="text-align: left"><p>Returns the name of the file (or
directory).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755795" class="indexterm"/> <code class="literal">getParent()</code>
</p></td><td style="text-align: left"><p> <code class="literal">String</code> </p></td><td style="text-align: left"><p>Returns the name of the parent
directory of the file (or directory).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755829" class="indexterm"/> <code class="literal">getPath()</code>
</p></td><td style="text-align: left"><p> <code class="literal">String</code> </p></td><td style="text-align: left"><p>Returns the path of the file (or
directory). (Not to be confused with <code class="literal">toPath()</code>).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755869" class="indexterm"/> <code class="literal">getTotalSpace()</code> </p></td><td style="text-align: left"><p> <code class="literal">long</code> </p></td><td style="text-align: left"><p>Get the size of the partition that
contains the file path in bytes or 0 if the path is
invalid.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755904" class="indexterm"/> <code class="literal">getUseableSpace()</code> </p></td><td style="text-align: left"><p> <code class="literal">long</code> </p></td><td style="text-align: left"><p>Get the number of bytes of
user-accessible unallocated space on the partition holding
this path or 0 if the path is invalid. This method attempts to
take into account user write permissions.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755940" class="indexterm"/> <code class="literal">isAbsolute()</code>
</p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Is the filename (or directory name)
absolute?</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id755974" class="indexterm"/> <code class="literal">isDirectory()</code> </p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Is the item a
directory?</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756008" class="indexterm"/> <code class="literal">isFile()</code>
</p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Is the item a file?</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756042" class="indexterm"/> <code class="literal">isHidden()</code>
</p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Is the item hidden?
(System-dependent.)</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756076" class="indexterm"/> <code class="literal">lastModified()</code> </p></td><td style="text-align: left"><p> <code class="literal">long</code> </p></td><td style="text-align: left"><p>Returns the last modification time
of the file (or directory).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756110" class="indexterm"/> <code class="literal">length()</code>
</p></td><td style="text-align: left"><p> <code class="literal">long</code> </p></td><td style="text-align: left"><p>Returns the length of the
file.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756146" class="indexterm"/> <code class="literal">list()</code>
</p></td><td style="text-align: left"><p> <code class="literal">String
[]</code> </p></td><td style="text-align: left"><p>Returns a list of files in the
directory.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756183" class="indexterm"/> <code class="literal">listFiles()</code>
</p></td><td style="text-align: left"><p> <code class="literal">File[]</code> </p></td><td style="text-align: left"><p>Returns the contents of the
directory as an array of <code class="literal">File</code> objects.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756222" class="indexterm"/> <code class="literal">listRoots()</code>
</p></td><td style="text-align: left"><p> <code class="literal">File[]</code> </p></td><td style="text-align: left"><p>Returns array of root filesystems if
any (e.g., C:/, D:/).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756257" class="indexterm"/> <code class="literal">mkdir()</code>
</p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Creates the
directory.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756291" class="indexterm"/> <code class="literal">mkdirs()</code>
</p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Creates all directories in the
path.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756324" class="indexterm"/> <code class="literal">renameTo(File</code>
<em class="replaceable"><code>dest</code></em> <code class="literal">)</code> </p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Renames the file (or
directory).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756367" class="indexterm"/> <code class="literal">setExecutable()</code> </p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Sets execute permissions for the
file.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756401" class="indexterm"/> <code class="literal">setLastModified()</code> </p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Sets the last-modified time of the
file (or directory).</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756436" class="indexterm"/> <code class="literal">setReadable()</code> </p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Sets read permissions for the
file.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756470" class="indexterm"/> <code class="literal">setReadOnly()</code> </p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Sets the file to read-only
status.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756504" class="indexterm"/> <code class="literal">setWriteable()</code> </p></td><td style="text-align: left"><p> <code class="literal">boolean</code> </p></td><td style="text-align: left"><p>Sets the write permissions for the
file.</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756538" class="indexterm"/> <code class="literal">toPath()</code>
</p></td><td style="text-align: left"><p> <code class="literal">java.nio.file.Path</code> </p></td><td style="text-align: left"><p>Convert the File to an NIO File Path
(see the NIO File API). (Not to be confused with <code class="literal">getPath()</code>.)</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm12_id756578" class="indexterm"/> <code class="literal">toURL()</code>
</p></td><td style="text-align: left"><p> <code class="literal">java.net.URL</code> </p></td><td style="text-align: left"><p>Generates a URL object for the file
(or directory).<a id="I_indexterm12_id756606" class="indexterm"/><a id="I_indexterm12_id756613" class="indexterm"/><a id="I_indexterm12_id756620" class="indexterm"/></p></td></tr></tbody></table></div></div></div></div><div class="sect2" title="File Streams"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-12-SECT-2.2"/>File Streams</h2></div></div></div><p><a id="idx10707" class="indexterm"/>OK, you’re probably sick of hearing about files already
and we haven’t even written a byte yet! Well, now the fun begins. Java
provides two fundamental streams for reading from and writing to files:
<a id="I_indexterm12_id756652" class="indexterm"/><code class="literal">FileInputStream</code> and
<a id="I_indexterm12_id756663" class="indexterm"/><code class="literal">FileOutputStream</code>. These
streams provide the basic byte-oriented <code class="literal">InputStream</code> and <code class="literal">OutputStream</code> functionality that is applied to
reading and writing files. They can be combined with the filter streams
described earlier to work with files in the same way as other stream
communications.</p><p>You can create a <code class="literal">FileInputStream</code> from a <code class="literal">String</code> pathname or a <code class="literal">File</code> object:</p><a id="I_12_tt794"/><pre class="programlisting"> <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">"/etc/passwd"</code> <code class="o">);</code></pre><p>When you create a <code class="literal">FileInputStream</code>, the Java runtime system
attempts to open the specified file. Thus, the <code class="literal">FileInputStream</code> constructors can throw a
<a id="I_indexterm12_id756727" class="indexterm"/><code class="literal">FileNotFoundException</code>
if the specified file doesn’t exist or an <a id="I_indexterm12_id756739" class="indexterm"/><code class="literal">IOException</code> if some
other I/O error occurs. You must catch these exceptions in your code.
Wherever possible, it’s a good idea to get in the habit of using the new
Java 7 <code class="literal">try</code>-with-resources construct
to automatically close files for you when you are finished with
them:</p><a id="I_programlisting12_id756759"/><pre class="programlisting"><code class="k">try</code> <code class="o">(</code> <code class="n">FileInputStream</code> <code class="n">fin</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FileInputStream</code><code class="o">(</code> <code class="s">"/etc/passwd"</code> <code class="o">)</code> <code class="o">)</code> <code class="o">{</code>
<code class="o">....</code>
<code class="c1">// Fin will be closed automatically if needed upon exiting the try clause.</code>
<code class="o">}</code></pre><p>When the stream is first created, its <code class="literal">available()</code> method and the <code class="literal">File</code> object’s <code class="literal">length()</code> method should return the same
value.</p><p>To read characters from a file as a <code class="literal">Reader</code>, you can wrap an <code class="literal">InputStreamReader</code> around a <code class="literal">FileInputStream</code>. If you want to use the
default character-encoding scheme for the platform, you can use the
<code class="literal">FileReader</code> class instead, which is
provided as a convenience. <code class="literal">FileReader</code>
is just a <code class="literal">FileInputStream</code> wrapped in
an <code class="literal">InputStreamReader</code> with some
defaults. For some crazy reason, you can’t specify a character encoding
for the <code class="literal">FileReader</code> to use, so it’s
probably best to ignore it and use <code class="literal">InputStreamReader</code> with <code class="literal">FileInputStream</code>.</p><p>The following class, <code class="literal">ListIt</code> ,
is a small utility that sends the contents of a file or directory to
standard output:</p><a id="I_12_tt795"/><pre class="programlisting"> <code class="c1">//file: ListIt.java</code>
<code class="kn">import</code> <code class="nn">java.io.*</code><code class="o">;</code>
<code class="kd">class</code> <code class="nc">ListIt</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="n">args</code><code class="o">[]</code> <code class="o">)</code> <code class="kd">throws</code> <code class="n">Exception</code> <code class="o">{</code>
<code class="n">File</code> <code class="n">file</code> <code class="o">=</code> <code class="k">new</code> <code class="n">File</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="k">if</code> <code class="o">(</code> <code class="o">!</code><code class="n">file</code><code class="o">.</code><code class="na">exists</code><code class="o">()</code> <code class="o">||</code> <code class="o">!</code><code class="n">file</code><code class="o">.</code><code class="na">canRead</code><code class="o">()</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">"Can't read "</code> <code class="o">+</code> <code class="n">file</code> <code class="o">);</code>
<code class="k">return</code><code class="o">;</code>
<code class="o">}</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">file</code><code class="o">.</code><code class="na">isDirectory</code><code class="o">()</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">String</code> <code class="o">[]</code> <code class="n">files</code> <code class="o">=</code> <code class="n">file</code><code class="o">.</code><code class="na">list</code><code class="o">();</code>
<code class="k">for</code> <code class="o">(</code> <code class="n">String</code> <code class="n">file</code> <code class="o">:</code> <code class="n">files</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="n">file</code> <code class="o">);</code>
<code class="o">}</code> <code class="k">else</code>
<code class="k">try</code> <code class="o">{</code>
<code class="n">Reader</code> <code class="n">ir</code> <code class="o">=</code> <code class="k">new</code> <code class="n">InputStreamReader</code><code class="o">(</code>
<code class="k">new</code> <code class="nf">FileInputStream</code><code class="o">(</code> <code class="n">file</code> <code class="o">)</code> <code class="o">);</code>
<code class="n">BufferedReader</code> <code class="n">in</code> <code class="o">=</code> <code class="k">new</code> <code class="n">BufferedReader</code><code class="o">(</code> <code class="n">ir</code> <code class="o">);</code>
<code class="n">String</code> <code class="n">line</code><code class="o">;</code>
<code class="k">while</code> <code class="o">((</code><code class="n">line</code> <code class="o">=</code> <code class="n">in</code><code class="o">.</code><code class="na">readLine</code><code class="o">())</code> <code class="o">!=</code> <code class="kc">null</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="n">line</code><code class="o">);</code>
<code class="o">}</code>
<code class="k">catch</code> <code class="o">(</code> <code class="n">FileNotFoundException</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">"File Disappeared"</code> <code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p><code class="literal">ListIt</code> constructs a <code class="literal">File</code> object from its first command-line
argument and tests the <code class="literal">File</code> to see
whether it exists and is readable. If the <code class="literal">File</code> is a directory, <code class="literal">ListIt</code> outputs the names of the files in the
directory. Otherwise, <code class="literal">ListIt</code> reads
and outputs the file, line by line.</p><p>For writing files, you can create a <code class="literal">FileOutputStream</code> from a <code class="literal">String</code> pathname or a <code class="literal">File</code> object. Unlike <code class="literal">FileInputStream</code>, however, the <code class="literal">FileOutputStream</code> constructors don’t throw a
<code class="literal">FileNotFoundException</code>. If the
specified file doesn’t exist, the <code class="literal">FileOutputStream</code> creates the file. The
<code class="literal">FileOutputStream</code> constructors can
throw an <code class="literal">IOException</code> if some other
I/O error occurs, so you still need to handle this exception.</p><p>If the specified file does exist, the <code class="literal">FileOutputStream</code> opens it for writing. When
you subsequently call the <code class="literal">write()</code>
method, the new data overwrites the current contents of the file. If you
need to append data to an existing file, you can use a form of the
constructor that accepts a Boolean <code class="literal">append</code> flag:</p><a id="I_12_tt796"/><pre class="programlisting"> <code class="n">FileInputStream</code> <code class="n">fooOut</code> <code class="o">=</code>
<code class="k">new</code> <code class="nf">FileOutputStream</code><code class="o">(</code> <code class="n">fooFile</code> <code class="o">);</code> <code class="c1">// overwrite fooFile</code>
<code class="n">FileInputStream</code> <code class="n">pwdOut</code> <code class="o">=</code>
<code class="k">new</code> <code class="nf">FileOutputStream</code><code class="o">(</code> <code class="s">"/etc/passwd"</code><code class="o">,</code> <code class="kc">true</code> <code class="o">);</code> <code class="c1">// append</code></pre><p>Another way to append data to files is with <code class="literal">RandomAccessFile</code>, which we’ll discuss
shortly.</p><p>Just as with reading, to write characters (instead of bytes) to a
file, you can wrap an <a id="I_indexterm12_id757004" class="indexterm"/><code class="literal">OutputStreamWriter</code>
around a <code class="literal">FileOutputStream</code>. If you
want to use the default character-encoding scheme, you can use the
<code class="literal">FileWriter</code> class instead, which is
provided as a convenience.</p><p>The following example reads a line of data from standard input and
writes it to the file <span class="emphasis"><em>/tmp/foo.txt</em></span>:</p><a id="I_12_tt797"/><pre class="programlisting"> <code class="n">String</code> <code class="n">s</code> <code class="o">=</code> <code class="k">new</code> <code class="n">BufferedReader</code><code class="o">(</code>
<code class="k">new</code> <code class="nf">InputStreamReader</code><code class="o">(</code> <code class="n">System</code><code class="o">.</code><code class="na">in</code> <code class="o">)</code> <code class="o">).</code><code class="na">readLine<