2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package org.apache.karaf.tooling.utils;
20 import java.nio.channels.FileChannel;
22 public class IoUtils {
24 private static final long FILE_COPY_BUFFER_SIZE = 1024 * 30;
26 public static void deleteRecursive(File file) {
28 if (file.isDirectory()) {
29 File[] children = file.listFiles();
30 if (children != null) {
31 for (File child : children) {
32 deleteRecursive(child);
40 public static void copyDirectory(final File srcDir, final File destDir) throws IOException {
41 if (srcDir == null || !srcDir.exists())
43 if (destDir == null || !destDir.exists())
46 final File[] srcFiles = srcDir.listFiles();
47 if (srcFiles == null) { // null if abstract pathname does not denote a directory, or if an I/O error occurs
48 throw new IOException("Failed to list contents of " + srcDir);
50 if (destDir.exists()) {
51 if (destDir.isDirectory() == false) {
52 throw new IOException("Destination '" + destDir + "' exists but is not a directory");
55 if (!destDir.mkdirs() && !destDir.isDirectory()) {
56 throw new IOException("Destination '" + destDir + "' directory cannot be created");
59 if (destDir.canWrite() == false) {
60 throw new IOException("Destination '" + destDir + "' cannot be written to");
62 for (final File srcFile : srcFiles) {
63 final File dstFile = new File(destDir, srcFile.getName());
64 if (srcFile.isDirectory()) {
65 copyDirectory(srcFile, dstFile);
67 copyFile(srcFile, dstFile);
72 public static void copyFile(final File srcFile, final File destFile) throws IOException {
73 if (destFile.exists() && destFile.isDirectory()) {
74 throw new IOException("Destination '" + destFile + "' exists but is a directory");
77 FileInputStream fis = null;
78 FileOutputStream fos = null;
79 FileChannel input = null;
80 FileChannel output = null;
82 fis = new FileInputStream(srcFile);
83 fos = new FileOutputStream(destFile);
84 input = fis.getChannel();
85 output = fos.getChannel();
86 final long size = input.size(); // TODO See IO-386
90 final long remain = size - pos;
91 count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain;
92 final long bytesCopied = output.transferFrom(input, pos, count);
93 if (bytesCopied == 0) { // IO-385 - can happen if file is truncated after caching the size
94 break; // ensure we don't loop forever
100 try { output.close(); } catch (Exception e) { }
103 try { fos.close(); } catch (Exception e) { }
106 try { input.close(); } catch (Exception e) { }
109 try { fis.close(); } catch (Exception e) { }
113 final long srcLen = srcFile.length(); // TODO See IO-386
114 final long dstLen = destFile.length(); // TODO See IO-386
115 if (srcLen != dstLen) {
116 throw new IOException("Failed to copy full contents from '" +
117 srcFile + "' to '" + destFile + "' Expected length: " + srcLen +" Actual: " + dstLen);