2525import java .io .InputStream ;
2626import java .io .OutputStream ;
2727import java .net .URL ;
28+ import java .nio .channels .FileChannel ;
2829import java .util .Collection ;
2930import java .util .Date ;
3031import java .util .Iterator ;
@@ -105,6 +106,38 @@ public FileUtils() {
105106 */
106107 public static final File [] EMPTY_FILE_ARRAY = new File [0 ];
107108
109+ //-----------------------------------------------------------------------
110+ /**
111+ * Opens a {@link FileInputStream} for the specified file, providing better
112+ * error messages than simply calling <code>new FileInputStream(file)</code>.
113+ * <p>
114+ * At the end of the method either the stream will be successfully opened,
115+ * or an exception will have been thrown.
116+ * <p>
117+ * An exception is thrown if the file does not exist.
118+ * An exception is thrown if the file object exists but is a directory.
119+ * An exception is thrown if the file exists but cannot be read.
120+ *
121+ * @param file the file to open for input, not null
122+ * @throws IOException if the file does not exist
123+ * @throws IOException if the file object is a directory
124+ * @throws IOException if the file cannot be read
125+ * @since Commons IO 1.3
126+ */
127+ public static FileInputStream openInputStream (File file ) throws IOException {
128+ if (file .exists ()) {
129+ if (file .isDirectory ()) {
130+ throw new IOException ("File '" + file + "' exists but is a directory" );
131+ }
132+ if (file .canRead () == false ) {
133+ throw new IOException ("File '" + file + "' cannot be read" );
134+ }
135+ } else {
136+ throw new IOException ("File '" + file + "' does not exist" );
137+ }
138+ return new FileInputStream (file );
139+ }
140+
108141 //-----------------------------------------------------------------------
109142 /**
110143 * Opens a {@link FileOutputStream} for the specified file, checking and
@@ -119,8 +152,9 @@ public FileUtils() {
119152 * An exception is thrown if the file exists but cannot be written to.
120153 * An exception is thrown if the parent directory cannot be created.
121154 *
122- * @param file the file to create , not null
155+ * @param file the file to open for output , not null
123156 * @throws IOException if the file object is a directory
157+ * @throws IOException if the file cannot be written to
124158 * @throws IOException if a parent directory needs creating but that fails
125159 * @since Commons IO 1.3
126160 */
@@ -918,17 +952,16 @@ public static boolean waitFor(File file, int seconds) {
918952 * the default encoding can differ between platforms and will have
919953 * inconsistent results.
920954 *
921- * @param file the file to read
955+ * @param file the file to read, not null
922956 * @param encoding the encoding to use, null means platform default
923- * @return the file contents or null if read failed
957+ * @return the file contents, never null
924958 * @throws IOException in case of an I/O error
925959 * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
926960 */
927- public static String readFileToString (
928- File file , String encoding ) throws IOException {
961+ public static String readFileToString (File file , String encoding ) throws IOException {
929962 InputStream in = null ;
930963 try {
931- in = new FileInputStream (file );
964+ in = openInputStream (file );
932965 return IOUtils .toString (in , encoding );
933966 } finally {
934967 IOUtils .closeQuietly (in );
@@ -939,15 +972,15 @@ public static String readFileToString(
939972 * Reads the contents of a file into a byte array.
940973 * The file is always closed.
941974 *
942- * @param file the file to read
943- * @return the file contents or null if read failed
975+ * @param file the file to read, not null
976+ * @return the file contents, never null
944977 * @throws IOException in case of an I/O error
945978 * @since Commons IO 1.1
946979 */
947980 public static byte [] readFileToByteArray (File file ) throws IOException {
948981 InputStream in = null ;
949982 try {
950- in = new FileInputStream (file );
983+ in = openInputStream (file );
951984 return IOUtils .toByteArray (in );
952985 } finally {
953986 IOUtils .closeQuietly (in );
@@ -962,17 +995,17 @@ public static byte[] readFileToByteArray(File file) throws IOException {
962995 * the default encoding can differ between platforms and will have
963996 * inconsistent results.
964997 *
965- * @param file the file to read
998+ * @param file the file to read, not null
966999 * @param encoding the encoding to use, null means platform default
967- * @return the list of Strings representing each line in the file
1000+ * @return the list of Strings representing each line in the file, never null
9681001 * @throws IOException in case of an I/O error
9691002 * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
9701003 * @since Commons IO 1.1
9711004 */
9721005 public static List readLines (File file , String encoding ) throws IOException {
9731006 InputStream in = null ;
9741007 try {
975- in = new FileInputStream (file );
1008+ in = openInputStream (file );
9761009 return IOUtils .readLines (in , encoding );
9771010 } finally {
9781011 IOUtils .closeQuietly (in );
@@ -1008,7 +1041,7 @@ public static List readLines(File file, String encoding) throws IOException {
10081041 * the default encoding can differ between platforms and will have
10091042 * inconsistent results.
10101043 *
1011- * @param file the file to read
1044+ * @param file the file to read, not null
10121045 * @param encoding the encoding to use, null means platform default
10131046 * @return an Iterator of the lines in the file, never null
10141047 * @throws IOException in case of an I/O error (file closed)
@@ -1017,7 +1050,7 @@ public static List readLines(File file, String encoding) throws IOException {
10171050 public static LineIterator lineIterator (File file , String encoding ) throws IOException {
10181051 InputStream in = null ;
10191052 try {
1020- in = new FileInputStream (file );
1053+ in = openInputStream (file );
10211054 return IOUtils .lineIterator (in , encoding );
10221055 } catch (IOException ex ) {
10231056 IOUtils .closeQuietly (in );
@@ -1046,8 +1079,9 @@ public static LineIterator lineIterator(File file, String encoding) throws IOExc
10461079 * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
10471080 */
10481081 public static void writeStringToFile (File file , String data , String encoding ) throws IOException {
1049- OutputStream out = openOutputStream ( file ) ;
1082+ OutputStream out = null ;
10501083 try {
1084+ out = openOutputStream (file );
10511085 IOUtils .write (data , out , encoding );
10521086 } finally {
10531087 IOUtils .closeQuietly (out );
@@ -1066,8 +1100,9 @@ public static void writeStringToFile(File file, String data, String encoding) th
10661100 * @since Commons IO 1.1
10671101 */
10681102 public static void writeByteArrayToFile (File file , byte [] data ) throws IOException {
1069- OutputStream out = openOutputStream ( file ) ;
1103+ OutputStream out = null ;
10701104 try {
1105+ out = openOutputStream (file );
10711106 out .write (data );
10721107 } finally {
10731108 IOUtils .closeQuietly (out );
@@ -1118,8 +1153,9 @@ public static void writeLines(File file, String encoding, Collection lines) thro
11181153 * @since Commons IO 1.1
11191154 */
11201155 public static void writeLines (File file , String encoding , Collection lines , String lineEnding ) throws IOException {
1121- OutputStream out = openOutputStream ( file ) ;
1156+ OutputStream out = null ;
11221157 try {
1158+ out = openOutputStream (file );
11231159 IOUtils .writeLines (lines , lineEnding , out , encoding );
11241160 } finally {
11251161 IOUtils .closeQuietly (out );
0 commit comments