com.palantir.util.file.TempFileUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of atlasdb-commons Show documentation
Show all versions of atlasdb-commons Show documentation
Palantir open source project
/*
* (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
*
* 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 com.palantir.util.file;
import com.google.common.io.BaseEncoding;
import com.palantir.logsafe.exceptions.SafeIoException;
import java.io.File;
import java.io.IOException;
import java.util.Random;
public final class TempFileUtils {
private TempFileUtils() {
/**/
}
private static final Random tempFileRandom = new Random();
private static byte[] generateRandomBytes(int n) {
byte[] bytes = new byte[n];
synchronized (tempFileRandom) {
tempFileRandom.nextBytes(bytes);
}
return bytes;
}
public static File createTempFile(String prefix, String suffix) throws IOException {
ensureTempDirectoryExists();
byte[] bytes = generateRandomBytes(32);
return File.createTempFile(prefix + bytesToHex(bytes), suffix);
}
public static File createTempFile(String prefix, String suffix, File directory) throws IOException {
ensureTempDirectoryExists();
byte[] bytes = generateRandomBytes(32);
return File.createTempFile(prefix + bytesToHex(bytes), suffix, directory);
}
public static File createTempDirectory(final String prefix, final String suffix) throws IOException {
final File tempFile = createTempFile(prefix, suffix);
if (tempFile.exists() && !tempFile.delete()) {
throw new SafeIoException("Unable to delete file to create directory.");
}
if (!tempFile.mkdir()) {
throw new SafeIoException("Unable to create directory.");
}
return tempFile;
}
/**
* Ensures that the file exists
*/
public static void ensureFileExists(File file) throws IOException {
if (!file.exists()) {
file.createNewFile();
}
}
/**
* Ensures that the tmp directory in the java.io.tmpdir system property exists
*/
public static void ensureTempDirectoryExists() throws IOException {
String tmpDirectoryPath = System.getProperty("java.io.tmpdir");
ensureDirectoryExists(tmpDirectoryPath);
}
/**
* Ensures that the directory specified by the path exists
*/
public static void ensureDirectoryExists(String path) throws IOException {
File tmpDirectory = new File(path);
if (!mkdirsWithRetry(tmpDirectory)) {
throw new IOException("Failed to create directory " + tmpDirectory.getAbsolutePath());
}
}
/**
* A thread-safer mkdirs. mkdirs() will fail if another thread creates one of the directories it
* means to create before it does. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4742723
*
* This attempts the mkdirs() multiple times, so that if another thread does create one of the
* directories, the next call to mkdirs() will take that into account.
*
* Note: this returns true iff the file f ends up being a directory, contrary to mkdirs(), which
* returns false if it existed before the call.
*/
public static boolean mkdirsWithRetry(final File f) {
if (f.exists()) {
return f.isDirectory();
}
for (int i = 0; i < 10 && !f.isDirectory(); ++i) {
f.mkdirs();
}
return f.isDirectory();
}
private static String bytesToHex(byte... bytes) {
return BaseEncoding.base16().lowerCase().encode(bytes);
}
}