UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

323 lines (317 loc) 67.4 kB
<?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">&lt;</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<