/**
* 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.cassandra.io.util;
import java.io.*;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileUtils
{
private static Logger logger_ = LoggerFactory.getLogger(FileUtils.class);
private static final DecimalFormat df_ = new DecimalFormat("#.##");
private static final double kb_ = 1024d;
private static final double mb_ = 1024*1024d;
private static final double gb_ = 1024*1024*1024d;
private static final double tb_ = 1024*1024*1024*1024d;
public static void deleteWithConfirm(String file) throws IOException
{
deleteWithConfirm(new File(file));
}
public static void deleteWithConfirm(File file) throws IOException
{
assert file.exists() : "attempted to delete non-existing file " + file.getName();
if (logger_.isDebugEnabled())
logger_.debug("Deleting " + file.getName());
if (!file.delete())
{
throw new IOException("Failed to delete " + file.getAbsolutePath());
}
}
public static void renameWithConfirm(File from, File to) throws IOException
{
assert from.exists();
if (logger_.isDebugEnabled())
logger_.debug((String.format("Renaming %s to %s", from.getPath(), to.getPath())));
if (!from.renameTo(to))
throw new IOException(String.format("Failed to rename %s to %s", from.getPath(), to.getPath()));
}
public static void truncate(String path, long size) throws IOException
{
RandomAccessFile file;
try
{
file = new RandomAccessFile(path, "rw");
}
catch (FileNotFoundException e)
{
throw new RuntimeException(e);
}
try
{
file.getChannel().truncate(size);
}
finally
{
file.close();
}
}
public static void closeQuietly(Closeable c)
{
try
{
if (c != null)
c.close();
}
catch (Exception e)
{
logger_.warn("Failed closing stream", e);
}
}
public static void close(Iterable<? extends Closeable> cs) throws IOException
{
IOException e = null;
for (Closeable c : cs)
{
try
{
if (c != null)
c.close();
}
catch (IOException ex)
{
e = ex;
logger_.warn("Failed closing stream " + c, ex);
}
}
if (e != null)
throw e;
}
public static class FileComparator implements Comparator<File>
{
public int compare(File f, File f2)
{
return (int)(f.lastModified() - f2.lastModified());
}
}
public static void createDirectory(String directory) throws IOException
{
File file = new File(directory);
if (!file.exists())
{
if (!file.mkdirs())
{
throw new IOException("unable to mkdirs " + directory);
}
}
}
public static void createFile(String directory) throws IOException
{
File file = new File(directory);
if ( !file.exists() )
file.createNewFile();
}
public static boolean isExists(String filename) throws IOException
{
File file = new File(filename);
return file.exists();
}
public static boolean delete(String file)
{
File f = new File(file);
return f.delete();
}
public static boolean delete(List<String> files) throws IOException
{
boolean bVal = true;
for ( int i = 0; i < files.size(); ++i )
{
String file = files.get(i);
bVal = delete(file);
if (bVal)
{
if (logger_.isDebugEnabled())
logger_.debug("Deleted file {}", file);
files.remove(i);
}
}
return bVal;
}
public static void delete(File[] files) throws IOException
{
for ( File file : files )
{
file.delete();
}
}
public static String stringifyFileSize(double value)
{
double d;
if ( value >= tb_ )
{
d = value / tb_;
String val = df_.format(d);
return val + " TB";
}
else if ( value >= gb_ )
{
d = value / gb_;
String val = df_.format(d);
return val + " GB";
}
else if ( value >= mb_ )
{
d = value / mb_;
String val = df_.format(d);
return val + " MB";
}
else if ( value >= kb_ )
{
d = value / kb_;
String val = df_.format(d);
return val + " KB";
}
else
{
String val = df_.format(value);
return val + " bytes";
}
}
/**
* Deletes all files and subdirectories under "dir".
* @param dir Directory to be deleted
* @throws IOException if any part of the tree cannot be deleted
*/
public static void deleteRecursive(File dir) throws IOException
{
if (dir.isDirectory())
{
String[] children = dir.list();
for (String child : children)
deleteRecursive(new File(dir, child));
}
// The directory is now empty so now it can be smoked
deleteWithConfirm(dir);
}
public static void skipBytesFully(DataInput in, int bytes) throws IOException
{
int n = 0;
while (n < bytes)
{
int skipped = in.skipBytes(bytes - n);
if (skipped == 0)
throw new EOFException("EOF after " + n + " bytes out of " + bytes);
n += skipped;
}
}
public static void skipBytesFully(DataInput in, long bytes) throws IOException
{
long n = 0;
while (n < bytes)
{
int m = (int) Math.min(Integer.MAX_VALUE, bytes - n);
int skipped = in.skipBytes(m);
if (skipped == 0)
throw new EOFException("EOF after " + n + " bytes out of " + bytes);
n += skipped;
}
}
}