Java tutorial
/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import net.rim.ejde.internal.core.IConstants; import org.apache.log4j.Logger; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** * A utility class to manipulate files. * * @author dmeng */ public class FileUtils { private static final Logger log = Logger.getLogger(FileUtils.class); /** * Copy the source file to the destination file. An <code>IllegalArgumentException</code> will be thrown if the destination * file exists. * * @param src * The source file * @param dest * The destination file * @throws IOException * Any error during file copy */ public static void copy(File src, File dest) throws IOException { if ((src == null) || (dest == null)) { log.error("Source and Destination files cannot be null"); //$NON-NLS-1$ throw new IllegalArgumentException("Source and Destination files cannot be null"); //$NON-NLS-1$ } if (!src.exists() || !src.canRead() || !src.isFile()) { log.error("Could not access or read file " + src); //$NON-NLS-1$ throw new IllegalArgumentException("Could not access or read file " + src); //$NON-NLS-1$ } if (dest.exists()) { log.error("Destination file already exists: " + dest); //$NON-NLS-1$ throw new IllegalArgumentException("Destination file already exists: " + dest); //$NON-NLS-1$ } FileInputStream inputStream = null; FileOutputStream outputStream = null; FileChannel inputChannel = null, outputChannel = null; try { inputStream = new FileInputStream(src); outputStream = new FileOutputStream(dest); inputChannel = inputStream.getChannel(); outputChannel = outputStream.getChannel(); long count = 0, size = inputChannel.size(); while ((count += outputChannel.transferFrom(inputChannel, count, size - count)) < size) ; } catch (Throwable e) { log.error(e.getMessage(), e); } finally {// just in case the Eclipse API doesn't close it for whatever // reason. try { if (null != inputStream) inputStream.close(); if (outputStream != null) { outputStream.close(); } } catch (Throwable e) { ; log.error(e.getMessage(), e); } } } /** * Copy the source file to the destination file. An <code>IllegalArgumentException</code> will be thrown if the destination * file exists. * * @param inputStream * the input stream that acts as a source * @param dest * The destination file * * @throws IOException * Any error during file copy */ public static void copy(InputStream inputStream, File dest) throws IOException { if ((inputStream == null) || (dest == null)) { log.error("Source and Destination cannot be null"); //$NON-NLS-1$ throw new IllegalArgumentException("Source and Destination cannot be null"); //$NON-NLS-1$ } if (dest.exists()) { log.error("Destination file already exists: " + dest); //$NON-NLS-1$ throw new IllegalArgumentException("Destination file already exists: " + dest); //$NON-NLS-1$ } FileOutputStream outputStream = null; ReadableByteChannel inputChannel = null; FileChannel outputChannel = null; try { outputStream = new FileOutputStream(dest); inputChannel = Channels.newChannel(inputStream); outputChannel = outputStream.getChannel(); long count = 0, size = Long.MAX_VALUE; outputChannel.transferFrom(inputChannel, count, size); } catch (Throwable e) { log.error(e.getMessage(), e); } finally {// just in case the Eclipse API doesn't close it for whatever // reason. try { inputStream.close(); if (outputStream != null) { outputStream.close(); } } catch (Throwable e) { log.error(e.getMessage(), e); } } } /** * Copy the source file to the destination file. Overwrite it if the destination file exists. * * @param src * The source file * @param dest * The destination file * @throws IOException * Any error during file copy */ public static void copyOverwrite(File src, File dest) throws IOException { if ((src == null) || (dest == null)) { log.error("Source and Destination files cannot be null"); //$NON-NLS-1$ throw new IllegalArgumentException("Source and Destination files cannot be null"); //$NON-NLS-1$ } if (!src.exists() || !src.canRead() || !src.isFile()) { log.error("Could not access or read file " + src); //$NON-NLS-1$ throw new IllegalArgumentException("Could not access or read file " + src); //$NON-NLS-1$ } // delete the destination file if it exists. if (dest.exists()) { if (!dest.delete()) { log.warn("Could not replace file " + dest); //$NON-NLS-1$ return; } } copy(src, dest); } public static IStatus canChange(final java.io.File osFile) { return canChange(osFile, "Change Resource Problem", "Resource is read-only and cannot be changed: ", true, "\n\nDo you want to make the resource writable?"); } public static IStatus canChange(final java.io.File osFile, final String dialogTitle, final String errorMessage, final boolean showResourcePath, final String questionMessage) { IStatus result = Status.CANCEL_STATUS; if ((osFile != null) && (osFile.exists())) { if (osFile.canWrite()) { result = Status.OK_STATUS; } else { // prompt for making resource writable Display.getDefault().syncExec(new Runnable() { public void run() { StringBuffer buffer = new StringBuffer(); buffer.append(errorMessage); if (showResourcePath) { buffer.append(osFile.getAbsolutePath()); } buffer.append(questionMessage); String[] buttons = new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }; Shell shell = new Shell(); MessageDialog promptSaveDia = new MessageDialog(shell, dialogTitle, null, buffer.toString(), MessageDialog.WARNING, buttons, 0); int ret = promptSaveDia.open(); shell.dispose(); if (ret == Window.OK) { // make this resource writable setWritable(osFile); } } }); if (osFile.canWrite()) { result = Status.OK_STATUS; } } } return result; } public static void setWritable(java.io.File osFile) { // Since there is no method in Java to set writable directly, we have to // use following approach. java.io.File srcFile = osFile; java.io.File destFile = new java.io.File(srcFile.getParentFile(), String.valueOf(System.currentTimeMillis())); FileInputStream in = null; FileOutputStream out = null; FileChannel inChannel = null, outChannel = null; // create dest file try { destFile.createNewFile(); // copy content from source file to dest file in = new FileInputStream(srcFile); out = new FileOutputStream(destFile); inChannel = in.getChannel(); outChannel = out.getChannel(); inChannel.transferTo(0, inChannel.size(), outChannel); } catch (Throwable e) { log.error(e.getMessage(), e); } finally { try { if (null != inChannel) inChannel.close(); if (null != outChannel) outChannel.close(); } catch (Throwable e) { log.error(e.getMessage(), e); } } // delete source file boolean success = srcFile.delete(); if (!success) { destFile.delete(); throw new RuntimeException("source file can not be deleted:" + srcFile.getAbsolutePath()); } // rename dest file to source file destFile.renameTo(srcFile); } /** * Add the given <code>file</code> to the given </code>container</code>. * * @param container * @param file * @param createLink * @return */ public static IFile addResourceToProject(IContainer container, File file, Boolean createLink) { // TODO:Check if has package IProject iProject = container.getProject(); IFile iFile = null; iFile = container.getFile(new Path(file.getName())); if (iFile != null && !iFile.exists()) { if (createLink) { try { iFile.createLink(new Path(file.getAbsolutePath()), IResource.NONE, new NullProgressMonitor()); } catch (Exception e) { log.error("Error linking resource to project"); } } else { ImportUtils.copyFile(iProject, file, iFile.getProjectRelativePath()); } } return iFile; } /** * Returns where the resources (non-package) should be created * * @param iProject * @return */ public static IFolder getResFolder(IProject iProject) { IFolder sourceFolder = null; String resFolderName = ImportUtils.getProjectResFolderName(); if (resFolderName.length() > 0) { sourceFolder = iProject.getFolder(new Path(resFolderName)); } if (sourceFolder == null || !sourceFolder.exists()) { // Get the 1st found source folder sourceFolder = get1stNonDerivedSourceFolder(iProject); } return sourceFolder; } public static IFolder get1stNonDerivedSourceFolder(IProject iProject) { IFolder sfolder = null; IPackageFragmentRoot roots[] = ProjectUtils.getProjectSourceFolders(iProject); if (roots != null && roots.length > 0) { Collections.sort(Arrays.asList(roots), new Comparator<IPackageFragmentRoot>() { @Override public int compare(IPackageFragmentRoot root1, IPackageFragmentRoot root2) { return root1.getElementName().compareTo(root2.getElementName()); } }); for (int i = 0; i < roots.length; i++) { sfolder = iProject.getFolder(roots[i].getResource().getProjectRelativePath()); if (!sfolder.isDerived()) { break; } } } return sfolder; } public static void deleteAll(File[] files) { if (files == null) { throw new IllegalArgumentException("files cannot be null"); //$NON-NLS-1$ } for (File file : files) { if (!file.exists() || !file.canWrite()) { throw new IllegalArgumentException("Could not access or write file " + file); //$NON-NLS-1$ } if (file.isDirectory()) { deleteDir(file); } else { file.delete(); } } } /** * Reads the content of a file and returns an ArrayList with the data * * @param f * File that should be read * @return ArrayList of data */ public static List<String> readFile(File f) { List<String> data = new ArrayList<String>(); try { BufferedReader br = new BufferedReader(new FileReader(f)); while (br.ready()) { data.add(br.readLine()); } return data; } catch (FileNotFoundException e) { return null; } catch (IOException e) { return null; } } /** * Returns the file extension of the given file. * * @param f * @return File extension */ public static String getFileExtension(File f) { String fileName = f.getName(); int index = fileName.lastIndexOf(IConstants.DOT_MARK); if (index > 0 && index < fileName.length()) { String fileExtension = fileName.substring(index + 1); return fileExtension; } return IConstants.EMPTY_STRING; } private static void deleteDir(File file) { if (file == null) { throw new IllegalArgumentException("file cannot be null"); //$NON-NLS-1$ } if (!file.exists() || !file.canWrite()) { throw new IllegalArgumentException("Could not access or write file " + file); //$NON-NLS-1$ } for (File subFile : file.listFiles()) { if (!subFile.exists() || !subFile.canWrite()) { throw new IllegalArgumentException("Could not access or write file " + subFile); //$NON-NLS-1$ } if (subFile.isDirectory()) { deleteDir(subFile); } else { subFile.delete(); } } file.delete(); } }