mirror of
https://github.com/Maschell/JNUSLib.git
synced 2024-11-22 16:09:18 +01:00
Write new files from a Stream at first to a .tmp file. This avoids fragmentation.
This commit is contained in:
parent
2479572917
commit
51140fb7c7
8
src/de/mas/wiiu/jnus/utils/CheckedFunction.java
Normal file
8
src/de/mas/wiiu/jnus/utils/CheckedFunction.java
Normal file
@ -0,0 +1,8 @@
|
||||
package de.mas.wiiu.jnus.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CheckedFunction<T> {
|
||||
void apply(T t) throws IOException;
|
||||
}
|
@ -20,6 +20,8 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
@ -55,16 +57,41 @@ public final class FileUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void saveInputStreamToFile(@NonNull File outputFile, InputStream inputStream, long filesize) throws IOException {
|
||||
FileAsOutputStreamWrapper(outputFile, filesize, outputStream -> StreamUtils.saveInputStreamToOutputStream(inputStream, outputStream, filesize));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a byte array to a file (and overwrite it if its already exists) DOES NOT IF THE PATH/FILE EXIST OR IS IT EVEN A FILE
|
||||
* Allows to write into a target file as OutputStream with some extras. The provided OutputStream already has the needed memory allocated. This results in a
|
||||
* non-fragmented file.
|
||||
*
|
||||
* @param output
|
||||
* @param inputStream
|
||||
* @param outputFile
|
||||
* @param filesize
|
||||
* @param action
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void saveInputStreamToFile(@NonNull File output, InputStream inputStream, long filesize) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(output);
|
||||
StreamUtils.saveInputStreamToOutputStream(inputStream, out, filesize);
|
||||
public static void FileAsOutputStreamWrapper(@NonNull File outputFile, long filesize, CheckedFunction<OutputStream> action) throws IOException {
|
||||
// Create a new temp file which already has the target filesize allocated.
|
||||
String tempFilePath = outputFile.getAbsolutePath() + "." + outputFile.getAbsolutePath().hashCode() + ".part";
|
||||
File tempFile = new File(tempFilePath);
|
||||
if (tempFile.exists()) {
|
||||
tempFile.delete();
|
||||
}
|
||||
|
||||
tempFile.createNewFile();
|
||||
RandomAccessFile outStream = new RandomAccessFile(tempFilePath, "rw");
|
||||
outStream.setLength(filesize);
|
||||
outStream.seek(0L);
|
||||
|
||||
action.apply(new RandomFileOutputStream(outStream));
|
||||
|
||||
outStream.close();
|
||||
|
||||
// Rename temp file.
|
||||
if (outputFile.exists()) {
|
||||
outputFile.delete();
|
||||
}
|
||||
tempFile.renameTo(outputFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
111
src/de/mas/wiiu/jnus/utils/RandomFileOutputStream.java
Normal file
111
src/de/mas/wiiu/jnus/utils/RandomFileOutputStream.java
Normal file
@ -0,0 +1,111 @@
|
||||
package de.mas.wiiu.jnus.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class RandomFileOutputStream extends OutputStream {
|
||||
|
||||
// *****************************************************************************
|
||||
// INSTANCE PROPERTIES
|
||||
// *****************************************************************************
|
||||
|
||||
protected RandomAccessFile randomFile; // the random file to write to
|
||||
protected boolean sync; // whether to synchronize every write
|
||||
|
||||
// *****************************************************************************
|
||||
// INSTANCE CONSTRUCTION/INITIALIZATON/FINALIZATION, OPEN/CLOSE
|
||||
// *****************************************************************************
|
||||
|
||||
public RandomFileOutputStream(String fnm) throws IOException {
|
||||
this(fnm, false);
|
||||
}
|
||||
|
||||
public RandomFileOutputStream(String fnm, boolean syn) throws IOException {
|
||||
this(new File(fnm), syn);
|
||||
}
|
||||
|
||||
public RandomFileOutputStream(File fil) throws IOException {
|
||||
this(fil, false);
|
||||
}
|
||||
|
||||
public RandomFileOutputStream(RandomAccessFile ran) throws IOException {
|
||||
randomFile = ran;
|
||||
sync = false;
|
||||
}
|
||||
|
||||
public RandomFileOutputStream(File fil, boolean syn) throws IOException {
|
||||
super();
|
||||
|
||||
File par; // parent file
|
||||
|
||||
fil = fil.getAbsoluteFile();
|
||||
if ((par = fil.getParentFile()) != null) {
|
||||
Utils.createDir(par.getAbsolutePath());
|
||||
}
|
||||
randomFile = new RandomAccessFile(fil, "rw");
|
||||
sync = syn;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// INSTANCE METHODS - OUTPUT STREAM IMPLEMENTATION
|
||||
// *****************************************************************************
|
||||
|
||||
public void write(int val) throws IOException {
|
||||
randomFile.write(val);
|
||||
if (sync) {
|
||||
randomFile.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte[] val) throws IOException {
|
||||
randomFile.write(val);
|
||||
if (sync) {
|
||||
randomFile.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte[] val, int off, int len) throws IOException {
|
||||
randomFile.write(val, off, len);
|
||||
if (sync) {
|
||||
randomFile.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
if (sync) {
|
||||
randomFile.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
randomFile.close();
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// INSTANCE METHODS - RANDOM ACCESS EXTENSIONS
|
||||
// *****************************************************************************
|
||||
|
||||
public long getFilePointer() throws IOException {
|
||||
return randomFile.getFilePointer();
|
||||
}
|
||||
|
||||
public void setFilePointer(long pos) throws IOException {
|
||||
randomFile.seek(pos);
|
||||
}
|
||||
|
||||
public long getFileSize() throws IOException {
|
||||
return randomFile.length();
|
||||
}
|
||||
|
||||
public void setFileSize(long len) throws IOException {
|
||||
randomFile.setLength(len);
|
||||
}
|
||||
|
||||
public FileDescriptor getFD() throws IOException {
|
||||
return randomFile.getFD();
|
||||
}
|
||||
|
||||
} // END PUBLIC CLASS
|
Loading…
Reference in New Issue
Block a user