All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.log4j.helpers.FileHelper Maven / Gradle / Ivy

/*
 * Copyright 2015 Cisco Systems, Inc.
 *
 *  Licensed 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.log4j.helpers;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;

/**
 * @author Simon
 *         Park
 * @version 3.7
 */
public final class FileHelper {

  private static final FileHelper INSTANCE = new FileHelper();

  /**
   * @see Zip
   *      file specification
   */
  private static final long MAGIC_ZIP = ZipEntry.LOCSIG; // 0x04034b50L;

  /**
   * @see GZip file
   *      specification
   */
  private static final long MAGIC_GZIP = GZIPInputStream.GZIP_MAGIC; // 0x8b1f;

  public static final FileHelper getInstance() {
    return INSTANCE;
  }

  private FileHelper() {
    super();
  }

  public long sizeOf(final File file) {
    return this.isReadable(file) ? file.length() : 0L;
  }

  public boolean isEmpty(final File file) {
    return (this.sizeOf(file) == 0L);
  }

  /**
   * Delete with retry.
   * 
   * @param file
   * @return true if the file was successfully deleted.
   */
  public boolean deleteExisting(final File file) {
    if (!file.exists()) {
      return true;
    }
    boolean deleted = false;
    if (file.canWrite()) {
      deleted = file.delete();
    } else {
      LogLog.debug(file + " is not writeable for delete (retrying)");
    }
    if (!deleted) {
      if (!file.exists()) {
        deleted = true;
      } else {
        file.delete();
        deleted = (!file.exists());
      }
    }
    return deleted;
  }

  /**
   * Rename with retry.
   * 
   * @param from
   * @param to
   * @return true if the file was successfully renamed.
   */
  public boolean rename(final File from, final File to) {
    boolean renamed = false;
    if (this.isWriteable(from)) {
      renamed = from.renameTo(to);
    } else {
      LogLog.debug(from + " is not writeable for rename (retrying)");
    }
    if (!renamed) {
      from.renameTo(to);
      renamed = (!from.exists());
    }
    return renamed;
  }

  public boolean isReadable(final File file) {
    return (file.exists() && file.canRead());
  }

  public boolean isWriteable(final File file) {
    return (file.exists() && file.canWrite());
  }

  /**
   * @param file
   * @return The parent {@link java.io.File} if one exists, the current working
   *         directory otherwise.
   */
  public File parentDirOf(final File file) {
    File parentDir = file.getParentFile();
    if (parentDir == null) {
      parentDir = new File(System.getProperty("user.dir"));
    }
    return parentDir;
  }

  public boolean isCompressed(final File file) {
    return this.isZip(file) || this.isGZip(file);
  }

  public boolean isZip(final File file) {
    long magic = 0L;
    if (this.isReadable(file)) {
      // read enough bytes for a Java long
      final byte[] magicBytes = new byte[4];
      this.readBytes(file, magicBytes);
      magic = this.getUnsigned32Bit(magicBytes, 0);
    }
    return MAGIC_ZIP == magic;
  }

  public boolean isGZip(final File file) {
    long magic = 0L;
    if (this.isReadable(file)) {
      // read enough bytes for a Java short
      final byte[] magicBytes = new byte[2];
      this.readBytes(file, magicBytes);
      magic = this.getUnsigned16Bit(magicBytes, 0);
    }
    return MAGIC_GZIP == magic;
  }

  /*
   * Fetches unsigned 16-bit value from byte array at specified offset. The
   * bytes are in little-endian byte order.
   */
  private int getUnsigned16Bit(final byte[] bytes, final int offset) {
    return (bytes[offset] & 0xff) | ((bytes[offset + 1] & 0xff) << 8);
  }

  /*
   * Fetches unsigned 32-bit value from byte array at specified offset. The
   * bytes are in little-endian byte order.
   */
  private long getUnsigned32Bit(final byte[] bytes, final int offset) {
    return getUnsigned16Bit(bytes, offset)
        | ((long) getUnsigned16Bit(bytes, offset + 2) << 16);
  }

  private void readBytes(final File file, final byte[] bytes) {
    FileChannel channel = null;
    try {
      channel = new FileInputStream(file).getChannel();
      final ByteBuffer buffer = ByteBuffer.wrap(bytes);
      int bytesRead = channel.read(buffer);
      if (bytesRead != bytes.length) {
        LogLog.debug("Incomplete log file");
      }
    } catch (ClosedByInterruptException e) {
      // may occur if we're closing down
      LogLog.debug("Interrupted during log file read");
      Arrays.fill(bytes, (byte) 0);
    } catch (FileNotFoundException e) {
      LogLog.debug("Unable to open log file (it may have been scavenged) "
          + e.getMessage());
      Arrays.fill(bytes, (byte) 0);
    } catch (IOException e) {
      LogLog.error("Unable to read log file", e);
      Arrays.fill(bytes, (byte) 0);
    } finally {
      if (channel != null) {
        try {
          channel.close();
        } catch (IOException e) {
          LogLog.error("Unable to close log file", e);
        }
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy