/*
* Copyright (c) 2011, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
*
* 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 language governing permissions and limitations under
* the License.
*/
package com.google.dart.tools.core.test.util;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
/**
* The class <code>FileUtilities</code> implements utility methods used to create and manipulate
* files.
*/
public class FileUtilities {
/**
* Copy over all the files and directories contained in the source directory to the target
* directory.
*
* @param sourceDirectory the directory whose contents are to be copied
* @param targetDirectory the directory to which the contents are to be copied
*/
public static void copyDirectoryContents(File sourceDirectory, File targetDirectory)
throws IOException {
File[] children;
File sourceFile, targetFile;
if (!sourceDirectory.exists()) {
throw new IllegalArgumentException(
"sourceDirectory does not exist: " + sourceDirectory.getAbsolutePath()); //$NON-NLS-1$
} else if (!sourceDirectory.isDirectory()) {
throw new IllegalArgumentException(
"sourceDirectory is not a directory: " + sourceDirectory.getAbsolutePath()); //$NON-NLS-1$
}
if (!targetDirectory.exists()) {
targetDirectory.mkdirs();
} else if (!targetDirectory.isDirectory()) {
throw new IllegalArgumentException(
"targetDirectory is not a directory: " + targetDirectory.getAbsolutePath()); //$NON-NLS-1$
}
children = sourceDirectory.listFiles();
for (int i = 0; i < children.length; i++) {
sourceFile = children[i];
targetFile = new File(targetDirectory, sourceFile.getName());
if (sourceFile.isDirectory()) {
copyDirectoryContents(sourceFile, targetFile);
} else {
copyFile(sourceFile, targetFile);
}
}
}
/**
* Copy the contents of the given input file to the given output file.
*
* @param input the input file from which the contents are to be read
* @param output the output file to which the contents are to be written
* @throws IOException if the files cannot be either read or written
*/
public static void copyFile(File input, File output) throws IOException {
copyFile(new FileInputStream(input), new FileOutputStream(output));
}
/**
* Copy all of the bytes from the given input stream to the given output stream. Both streams will
* be closed after the operation.
*
* @param input the input stream from which bytes are to be read
* @param output the output stream to which bytes are to be written
* @throws IOException if the bytes cannot be either read or written
*/
public static void copyFile(InputStream input, OutputStream output) throws IOException {
int bufferSize, readSize;
byte[] buffer;
bufferSize = 8192;
buffer = new byte[bufferSize];
try {
readSize = input.read(buffer, 0, bufferSize);
while (readSize >= 0) {
output.write(buffer, 0, readSize);
readSize = input.read(buffer, 0, bufferSize);
}
} finally {
try {
input.close();
} catch (IOException exception) {
// ignore failures to close the input
}
try {
output.close();
} catch (IOException exception) {
// ignore failures to close the output
}
}
}
/**
* Copy the contents of the given input file to the given output file.
*
* @param input the input file from which the contents are to be read
* @param output the output file to which the contents are to be written
* @throws IOException if the files cannot be either read or written
*/
public static void copyFile(URL input, File output) throws IOException {
copyFile(input.openStream(), new FileOutputStream(output));
}
/**
* Create the given file, including any parent directories that do not already exist.
*
* @param file the file to be created
* @throws IOException if the file could not be created
*/
public static void create(File file) throws IOException {
File parent;
parent = file.getParentFile();
if (parent != null && !parent.exists()) {
if (!parent.mkdirs()) {
throw new IOException("Could not create directory " + parent.getAbsolutePath()); //$NON-NLS-1$
}
}
if (file.isDirectory()) {
if (!file.mkdir()) {
throw new IOException("Could not create directory " + file.getAbsolutePath()); //$NON-NLS-1$
}
} else {
file.createNewFile();
}
}
/**
* Delete the given file or directory. If the argument is a directory, then the contents of the
* directory will be deleted before the directory itself is deleted.
*
* @param file the file or directory to be deleted
*/
public static void delete(File file) {
if (file.isDirectory()) {
safelyDeleteContents(file);
}
file.delete();
}
/**
* Delete the contents of the given directory without deleting the directory itself.
*
* @param directory the directory whose contents are to be deleted
* @throws IllegalArgumentException if the argument is not a directory
*/
public static void deleteContents(File directory) {
if (!directory.isDirectory()) {
throw new IllegalArgumentException(
"Cannot delete file contents: \"" + directory.getAbsolutePath() + "\""); //$NON-NLS-1$
}
safelyDeleteContents(directory);
}
/**
* Return the base name of the given file. The base name is the portion of the name that occurs
* before the period or extension when a file name is assumed to be of the form
* <code>baseName '.' extension</code>.
*
* @return the base name of the given file
*/
public static String getBaseName(File file) {
String name;
int index;
name = file.getName();
index = name.lastIndexOf('.');
if (index >= 0) {
return name.substring(0, index);
}
return name;
}
/**
* Return the contents of the given file, interpreted as a string.
*
* @param file the file whose contents are to be returned
* @return the contents of the given file, interpreted as a string
* @throws IOException if the file contents could not be read
*/
public static String getContents(File file) throws IOException {
FileReader fileReader = null;
BufferedReader reader;
try {
fileReader = new FileReader(file);
reader = new BufferedReader(fileReader);
StringBuilder builder = new StringBuilder((int) file.length());
int nextChar = reader.read();
while (nextChar >= 0) {
builder.append((char) nextChar);
nextChar = reader.read();
}
return builder.toString();
} finally {
if (fileReader != null) {
fileReader.close();
}
}
}
/**
* Return the extension of the given file. The extension is the portion of the name that occurs
* after the final period when a file name is assumed to be of the form
* <code>baseName '.' extension</code>.
*
* @return the extension of the given file
*/
public static String getExtension(File file) {
String name;
int index;
name = file.getName();
index = name.lastIndexOf('.');
if (index >= 0) {
return name.substring(index + 1);
}
return "";
}
/**
* Return a directory with the given name in the given base directory. If the directory did not
* already exist it will be created. If there is a file of the same name in the base directory,
* then the directory name will be made unique by appending an integer to the base name.
*
* @return a directory with the given name in the given base directory
* @throws SecurityException if the directory cannot be accessed or created
*/
public static File getOrCreateDirectory(File baseDirectory, String baseName) {
File directory;
int index;
directory = new File(baseDirectory, baseName);
index = 1;
while (directory.exists() && !directory.isDirectory()) {
directory = new File(baseDirectory, baseName + index);
index++;
}
if (!directory.exists()) {
directory.mkdir();
}
return directory;
}
/**
* Return a file in the given directory whose name is composed from the given base name and
* extension (which should include the period), but which does not currently exist.
*
* @param directory the directory that should contain the file
* @param baseName the base name of the file
* @param extension the extension used for the file
* @return a unique file that can be created without overwriting any other file
*/
public static File getUniqueFile(File directory, String baseName, String extension) {
File file;
int index;
file = new File(directory, baseName + extension);
index = 1;
while (file.exists()) {
file = new File(directory, baseName + index + extension);
index++;
}
return file;
}
/**
* Overwrite the contents of the given file to the given contents.
*
* @param file the file whose contents are to be written
* @param contents the new contents for the file
* @throws IOException if the file contents could not be written
*/
public static void setContents(File file, String contents) throws IOException {
FileWriter fileWriter = null;
BufferedWriter writer;
try {
fileWriter = new FileWriter(file);
writer = new BufferedWriter(fileWriter);
writer.write(contents);
writer.flush();
} finally {
if (fileWriter != null) {
fileWriter.close();
}
}
}
/**
* Delete the contents of the given directory, given that we know it is a directory.
*
* @param directory the directory whose contents are to be deleted
*/
private static void safelyDeleteContents(File directory) {
File[] children;
children = directory.listFiles();
for (int i = 0; i < children.length; i++) {
delete(children[i]);
}
}
/**
* Disallow the creation of instances of this class.
*/
private FileUtilities() {
}
}