| /* |
| * 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 |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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.geode.internal.util; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.RandomAccessFile; |
| |
| /** |
| * Utility class for copying log files |
| * |
| * @since GemFire 6.5 |
| */ |
| public class LogFileUtils { |
| |
| |
| |
| /** |
| * The default buffer size to use. |
| */ |
| private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; |
| |
| /** |
| * Copy a file preserving the date. |
| * |
| * @param srcFile the validated source file, must not be <code>null</code> |
| * @param destFile the validated destination file, must not be <code>null</code> |
| * @throws IOException if an error occurs |
| */ |
| public static void copyFile(File srcFile, File destFile) throws IOException { |
| if (destFile.exists() && destFile.isDirectory()) { |
| throw new IOException("Destination '" + destFile + "' exists but is a directory"); |
| } |
| |
| FileInputStream input = new FileInputStream(srcFile); |
| try { |
| FileOutputStream output = new FileOutputStream(destFile); |
| try { |
| copy(input, output); |
| } finally { |
| close(output); |
| } |
| } finally { |
| close(input); |
| } |
| |
| if (srcFile.length() != destFile.length()) { |
| throw new IOException( |
| "Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'"); |
| } |
| destFile.setLastModified(srcFile.lastModified()); |
| } |
| |
| /** |
| * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>. |
| * |
| * @param input the <code>InputStream</code> to read from |
| * @param output the <code>OutputStream</code> to write to |
| * @return the number of bytes copied |
| * @throws NullPointerException if the input or output is null |
| * @throws IOException if an I/O error occurs |
| * @throws ArithmeticException if the byte count is too large |
| */ |
| public static int copy(InputStream input, OutputStream output) throws IOException { |
| byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; |
| long count = 0; |
| int n = 0; |
| while (-1 != (n = input.read(buffer))) { |
| output.write(buffer, 0, n); |
| count += n; |
| } |
| if (count > Integer.MAX_VALUE) { |
| return -1; |
| } |
| return (int) count; |
| } |
| |
| /** |
| * Close an <code>InputStream</code> ignoring exceptions. |
| * |
| * @param input the InputStream to close, may be null or already closed |
| */ |
| public static void close(InputStream input) { |
| try { |
| if (input != null) { |
| input.close(); |
| } |
| } catch (IOException ioe) { |
| // ignore |
| } |
| } |
| |
| /** |
| * Close an <code>OutputStream</code> ignoring exceptions. |
| * |
| * @param output the OutputStream to close, may be null or already closed |
| */ |
| public static void close(OutputStream output) { |
| try { |
| if (output != null) { |
| output.close(); |
| } |
| } catch (IOException ioe) { |
| // ignore |
| } |
| } |
| |
| |
| /** |
| * Delete a file ignoring exceptions. |
| * |
| * @param file to delete, can be <code>null</code> |
| */ |
| public static boolean delete(File file) { |
| if (file == null) { |
| return false; |
| } |
| try { |
| return file.delete(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| return false; |
| } |
| } |
| |
| |
| public static boolean renameAggressively(File oldFile, File newFile) { |
| boolean renameOK = oldFile.renameTo(newFile.getAbsoluteFile()); |
| if (!renameOK) { |
| try { |
| LogFileUtils.copyFile(oldFile, newFile.getAbsoluteFile()); |
| long timeStop = System.currentTimeMillis() + 600000; |
| boolean noDelete = !oldFile.delete(); |
| if (noDelete) { |
| try { |
| RandomAccessFile raf = new RandomAccessFile(oldFile, "rws"); |
| raf.setLength(0); |
| raf.close(); |
| noDelete = false; |
| } catch (Exception e) { |
| // ignore this |
| } |
| } |
| |
| if (noDelete) { |
| LogFileUtils.delete(newFile.getAbsoluteFile()); |
| renameOK = false; |
| } else { |
| renameOK = true; |
| } |
| } catch (IOException e) { |
| // ignore this and just return failure |
| } |
| } |
| return renameOK; |
| } |
| |
| } |