/**
* Licensed to the zk1931 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 com.github.zk1931.jzab;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
* A static class that contains file-related utility methods.
*/
final class FileUtils {
private static final Logger LOG = LoggerFactory.getLogger(FileUtils.class);
/**
* Disables the constructor.
*/
private FileUtils() {
}
/**
* Atomically writes a long integer to a file.
*
* This method writes a long integer to a file by first writing the long
* integer to a temporary file and then atomically moving it to the
* destination, overwriting the destination file if it already exists.
*
* @param value a long integer value to write.
* @param file file to write the value to.
* @throws IOException if an I/O error occurs.
*/
public static void writeLongToFile(long value, File file) throws IOException {
// Create a temp file in the same directory as the file parameter.
File temp = File.createTempFile(file.getName(), null,
file.getAbsoluteFile().getParentFile());
try (FileOutputStream fos = new FileOutputStream(temp);
OutputStreamWriter os =
new OutputStreamWriter(fos, Charset.forName("UTF-8"));
PrintWriter pw = new PrintWriter(os)) {
pw.print(Long.toString(value));
fos.getChannel().force(true);
}
atomicMove(temp, file);
LOG.debug("Atomically moved {} to {}", temp, file);
}
/**
* Reads a long integer from a file that was created by the
* {@link #writeLongToFile(long, File) writeIntToFile} method.
*
* @param file file to read the integer value from.
* @return the long integer value in the file
* @throws IOException if an I/O error occurs.
*/
public static long readLongFromFile(File file) throws IOException {
try (FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(
new InputStreamReader(fis, Charset.forName("UTF-8")))) {
long value = Long.parseLong(br.readLine());
return value;
}
}
/**
* Atomically writes properties to a file.
*
* This method writes properties to a file by first writing it to a
* temporary file and then atomically moving it to the destination,
* overwriting the destination file if it already exists.
*
* @param prop a Properties object to write.
* @param file file to write the value to.
* @throws IOException if an I/O error occurs.
*/
public static void writePropertiesToFile(Properties prop, File file)
throws IOException {
// Create a temp file in the same directory as the file parameter.
File temp = File.createTempFile(file.getName(), null,
file.getAbsoluteFile().getParentFile());
try (FileOutputStream fos = new FileOutputStream(temp)) {
prop.store(fos, "");
fos.getChannel().force(true);
}
atomicMove(temp, file);
LOG.debug("Atomically moved {} to {}", temp, file);
}
/**
* Reads the Properties from a file that was created by the
* {@link #writePropertiesToFile(Properties, File) writePropertiesToFile}
* method.
*
* @param file file to read the Properties object from.
* @return the Properties object in the file
* @throws IOException if an I/O error occurs.
*/
public static Properties readPropertiesFromFile(File file)
throws IOException {
try (FileInputStream fis = new FileInputStream(file)) {
Properties prop = new Properties();
prop.load(fis);
return prop;
}
}
/**
* Atomically move one file to another file.
*
* @param source the source file.
* @param dest the destination file.
* @throws IOException if an I/O error occurs.
*/
public static void atomicMove(File source, File dest) throws IOException {
Files.move(source.toPath(), dest.toPath(), ATOMIC_MOVE, REPLACE_EXISTING);
}
}