| <?xml version="1.0"?> |
| <!-- |
| Copyright 2002-2005 The Apache Software Foundation. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific iouage governing permissions and |
| limitations under the License. |
| --> |
| <document> |
| <properties> |
| <title>Best practices</title> |
| <author email="commons-dev@jakarta.apache.org">Commons Documentation Team</author> |
| </properties> |
| <body> |
| |
| <section name="Overview"> |
| <p> |
| This document presents a number of "best practices" in the IO area. |
| </p> |
| </section> |
| |
| <section name="java.io.File"> |
| |
| <p> |
| Often, you have to deal with files and filenames. There are many |
| things that can go wrong: |
| </p> |
| <ul> |
| <li>A class works in Unix but doesn't on Windows (or vice versa)</li> |
| <li>Invalid filenames due to double or missing path separators</li> |
| <li>UNC filenames (on Windows) don't work with my home-grown filename utility function</li> |
| <li>etc. etc.</li> |
| </ul> |
| <p> |
| These are good reasons not to work with filenames as Strings. Use |
| java.io.File instead which handles many of the above cases nicely. Too |
| many people are still always using Strings for filenames and risk |
| platform dependencies, for example. |
| </p> |
| <p> |
| Let's look at an example. BTW, it's one of the functions that made us |
| skip the class FilenameUtils for the initial release of Commons IO. |
| </p> |
| <source> |
| public static String getExtension(String filename) { |
| int index = filename.lastIndexOf('.'); |
| |
| if (-1 == index) { |
| return ""; |
| } else { |
| return filename.substring(index + 1); |
| } |
| }</source> |
| <p> |
| Easy enough? Right, but what happens if someone passes in a full path |
| instead of only a filename? Consider the following, perfectly legal path: |
| "C:\Temp\documentation.new\README" |
| </p> |
| <p> |
| Please use java.io.File for filenames instead of Strings. The functionality |
| that the class provides is well tested. In FileUtils you will find other |
| useful utility functions around java.io.File. |
| </p> |
| <p> |
| Instead of: |
| </p> |
| <source> |
| String tmpdir = "/var/tmp"; |
| String tmpfile = tmpdir + System.getProperty("file.separator") + "test.tmp"; |
| InputStream in = new java.io.FileInputStream(tmpfile);</source> |
| <p> |
| ...write: |
| </p> |
| <source> |
| File tmpdir = new File("/var/tmp"); |
| File tmpfile = new File(tmpdir, "test.tmp"); |
| InputStream in = new java.io.FileInputStream(tmpfile);</source> |
| |
| </section> |
| |
| <section name="Buffering streams"> |
| <p> |
| IO performance depends a lot from the buffering strategy. Usually, it's |
| quite fast to read packets with the size of 512 or 1024 bytes because |
| these sizes match well with the packet sizes used on harddisks in |
| file systems or file system caches. But as soon as you have to read only |
| a few bytes and that many times performance drops significantly. |
| </p> |
| <p> |
| Make sure you're properly buffering streams when reading or writing |
| streams, especially when working with files. Just decorate your |
| FileInputStream with a BufferedInputStream: |
| </p> |
| <source> |
| InputStream in = new java.io.FileInputStream(myfile); |
| try { |
| in = new java.io.BufferedInputStream(in); |
| |
| in.read(..... |
| } finally { |
| IOUtils.closeQuietly(in); |
| } |
| </source> |
| <p> |
| Pay attention that you're not buffering an already buffered stream. Some |
| components like XML parsers may do their own buffering so decorating |
| the InputStream you pass to the XML parser does nothing but slowing down |
| your code. If you use our CopyUtils or IOUtils you don't need to |
| additionally buffer the streams you use as the code in there already |
| buffers the copy process. Always check the Javadocs for information. |
| Another case where buffering is unnecessary is when you write to a |
| ByteArrayOutputStream since you're writing to memory only. |
| </p> |
| </section> |
| |
| </body> |
| |
| </document> |