mirror of
https://github.com/Maschell/JNUSLib.git
synced 2024-11-26 18:04:17 +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.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
@ -55,16 +57,41 @@ public final class FileUtils {
|
|||||||
return true;
|
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 outputFile
|
||||||
* @param inputStream
|
* @param filesize
|
||||||
|
* @param action
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static void saveInputStreamToFile(@NonNull File output, InputStream inputStream, long filesize) throws IOException {
|
public static void FileAsOutputStreamWrapper(@NonNull File outputFile, long filesize, CheckedFunction<OutputStream> action) throws IOException {
|
||||||
FileOutputStream out = new FileOutputStream(output);
|
// Create a new temp file which already has the target filesize allocated.
|
||||||
StreamUtils.saveInputStreamToOutputStream(inputStream, out, filesize);
|
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