konogonka/src/main/java/konogonka/Workers/NspXciExtractor.java

99 lines
3.9 KiB
Java

package konogonka.Workers;
import javafx.concurrent.Task;
import konogonka.Controllers.IRowModel;
import konogonka.ModelControllers.EMsgType;
import konogonka.ModelControllers.LogPrinter;
import java.io.*;
import java.util.List;
public class NspXciExtractor extends Task<Void> {
private long rawDataStartPos;
private List<IRowModel> models;
private String filesDestPath;
private LogPrinter logPrinter;
private File NspXciFile;
public NspXciExtractor(long rawDataStartPos, List<IRowModel> models, String filesDestPath, File NspXciFile){
this.rawDataStartPos = rawDataStartPos;
this.models = models;
this.filesDestPath = filesDestPath;
this.NspXciFile = NspXciFile;
this.logPrinter = new LogPrinter();
}
@Override
protected Void call() {
logPrinter.print("\tStart extracting", EMsgType.INFO);
for (IRowModel model: models){
logPrinter.print(filesDestPath+model.getFileName(), EMsgType.INFO);
File contentFile = new File(filesDestPath+model.getFileName());
long realFileOffset = rawDataStartPos + model.getFileOffset();
long realFileSize = model.getFileSize();
long readFrom = 0;
int readPice = 8388608; // 8mb NOTE: consider switching to 1mb 1048576
byte[] readBuf;
try{
BufferedOutputStream extractedFileOS = new BufferedOutputStream(new FileOutputStream(contentFile));
BufferedInputStream bufferedInStream = new BufferedInputStream(new FileInputStream(NspXciFile)); // TODO: refactor?
if (bufferedInStream.skip(realFileOffset) != realFileOffset) {
logPrinter.print("File length is less than offset noted", EMsgType.FAIL);
return null;
}
while (readFrom < realFileSize){
/*
if (isCancelled()) // Check if user interrupted process.
return false;
*/
if (realFileSize - readFrom < readPice)
readPice = Math.toIntExact(realFileSize - readFrom); // it's safe, I guarantee
readBuf = new byte[readPice];
if (bufferedInStream.read(readBuf) != readPice) {
logPrinter.print("Can't read required chunk from file", EMsgType.FAIL);
return null;
}
extractedFileOS.write(readBuf, 0, readPice);
//-----------------------------------------/
try {
logPrinter.updateProgress((readFrom+readPice)/(realFileSize/100.0) / 100.0);
}catch (InterruptedException ie){
getException().printStackTrace(); // TODO: Do something with this
}
//-----------------------------------------/
readFrom += readPice;
}
bufferedInStream.close();
extractedFileOS.close();
//-----------------------------------------/
try{
logPrinter.updateProgress(1.0);
}
catch (InterruptedException ie){
getException().printStackTrace(); // TODO: Do something with this
}
//-----------------------------------------/
}
catch (IOException ioe){
logPrinter.print("\tRead/Write error\n\t"+ioe.getMessage(), EMsgType.INFO);
return null;
}
}
close();
return null;
}
private void close(){
logPrinter.print("\tEnd extracting", EMsgType.INFO);
logPrinter.close();
}
}