/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * 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 org.apache.karaf.tooling.utils; import java.io.*; import java.nio.channels.FileChannel; public class IoUtils { private static final long FILE_COPY_BUFFER_SIZE = 1024 * 30; public static void deleteRecursive(File file) { if (file != null) { if (file.isDirectory()) { File[] children = file.listFiles(); if (children != null) { for (File child : children) { deleteRecursive(child); } } } file.delete(); } } public static void copyDirectory(final File srcDir, final File destDir) throws IOException { if (srcDir == null || !srcDir.exists()) return; if (destDir == null || !destDir.exists()) destDir.mkdirs(); // recurse final File[] srcFiles = srcDir.listFiles(); if (srcFiles == null) { // null if abstract pathname does not denote a directory, or if an I/O error occurs throw new IOException("Failed to list contents of " + srcDir); } if (destDir.exists()) { if (destDir.isDirectory() == false) { throw new IOException("Destination '" + destDir + "' exists but is not a directory"); } } else { if (!destDir.mkdirs() && !destDir.isDirectory()) { throw new IOException("Destination '" + destDir + "' directory cannot be created"); } } if (destDir.canWrite() == false) { throw new IOException("Destination '" + destDir + "' cannot be written to"); } for (final File srcFile : srcFiles) { final File dstFile = new File(destDir, srcFile.getName()); if (srcFile.isDirectory()) { copyDirectory(srcFile, dstFile); } else { copyFile(srcFile, dstFile); } } } public static void copyFile(final File srcFile, final File destFile) throws IOException { if (destFile.exists() && destFile.isDirectory()) { throw new IOException("Destination '" + destFile + "' exists but is a directory"); } FileInputStream fis = null; FileOutputStream fos = null; FileChannel input = null; FileChannel output = null; try { fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); input = fis.getChannel(); output = fos.getChannel(); final long size = input.size(); // TODO See IO-386 long pos = 0; long count = 0; while (pos < size) { final long remain = size - pos; count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain; final long bytesCopied = output.transferFrom(input, pos, count); if (bytesCopied == 0) { // IO-385 - can happen if file is truncated after caching the size break; // ensure we don't loop forever } pos += bytesCopied; } } finally { if (output != null) { try { output.close(); } catch (Exception e) { } } if (fos != null) { try { fos.close(); } catch (Exception e) { } } if (input != null) { try { input.close(); } catch (Exception e) { } } if (fis != null) { try { fis.close(); } catch (Exception e) { } } } final long srcLen = srcFile.length(); // TODO See IO-386 final long dstLen = destFile.length(); // TODO See IO-386 if (srcLen != dstLen) { throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "' Expected length: " + srcLen +" Actual: " + dstLen); } } }