blob: 7e071f01b98ea514ebf0c7853d7764b5e7d2b546 [file] [log] [blame]
/*
* 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;
}
}