* remove Java 6 compatibility hacks
This commit is contained in:
parent
e34266c79c
commit
4a590cc1b0
@ -4,10 +4,10 @@ import static net.filebot.Settings.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -50,17 +50,12 @@ public final class HistorySpooler {
|
||||
return new History(sessionHistory.sequences());
|
||||
}
|
||||
|
||||
RandomAccessFile f = new RandomAccessFile(persistentHistoryFile, "rw");
|
||||
FileChannel channel = f.getChannel();
|
||||
FileLock lock = channel.lock();
|
||||
try {
|
||||
History history = History.importHistory(new CloseShieldInputStream(Channels.newInputStream(channel))); // keep JAXB from closing the stream
|
||||
history.addAll(sessionHistory.sequences());
|
||||
return history;
|
||||
} finally {
|
||||
lock.release();
|
||||
channel.close();
|
||||
f.close();
|
||||
try (FileChannel channel = FileChannel.open(persistentHistoryFile.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
|
||||
try (FileLock lock = channel.lock()) {
|
||||
History history = History.importHistory(new CloseShieldInputStream(Channels.newInputStream(channel))); // keep JAXB from closing the stream
|
||||
history.addAll(sessionHistory.sequences());
|
||||
return history;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,35 +65,29 @@ public final class HistorySpooler {
|
||||
}
|
||||
|
||||
try {
|
||||
if (persistentHistoryFile.length() <= 0) {
|
||||
persistentHistoryFile.createNewFile();
|
||||
}
|
||||
RandomAccessFile f = new RandomAccessFile(persistentHistoryFile, "rw");
|
||||
FileChannel channel = f.getChannel();
|
||||
FileLock lock = channel.lock();
|
||||
try {
|
||||
History history = new History();
|
||||
if (persistentHistoryFile.length() > 0) {
|
||||
try {
|
||||
channel.position(0); // rewind
|
||||
history = History.importHistory(new CloseShieldInputStream(Channels.newInputStream(channel))); // keep JAXB from closing the stream
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Failed to load rename history.", e);
|
||||
try (FileChannel channel = FileChannel.open(persistentHistoryFile.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
|
||||
try (FileLock lock = channel.lock()) {
|
||||
History history = new History();
|
||||
|
||||
// load existing history from previous sessions
|
||||
if (channel.size() > 0) {
|
||||
try {
|
||||
channel.position(0);
|
||||
history = History.importHistory(new CloseShieldInputStream(Channels.newInputStream(channel))); // keep JAXB from closing the stream
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Failed to load rename history.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// write new combined history
|
||||
history.addAll(sessionHistory.sequences());
|
||||
|
||||
channel.position(0);
|
||||
History.exportHistory(history, new CloseShieldOutputStream(Channels.newOutputStream(channel))); // keep JAXB from closing the stream
|
||||
|
||||
sessionHistory.clear();
|
||||
persistentHistoryTotalSize = history.totalSize();
|
||||
}
|
||||
history.addAll(sessionHistory.sequences());
|
||||
|
||||
channel.position(0);
|
||||
History.exportHistory(history, new CloseShieldOutputStream(Channels.newOutputStream(channel))); // keep JAXB from closing the stream
|
||||
|
||||
sessionHistory.clear();
|
||||
persistentHistoryTotalSize = history.totalSize();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
lock.release();
|
||||
channel.close();
|
||||
f.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Failed to write rename history.", e);
|
||||
|
@ -14,10 +14,8 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -25,6 +23,7 @@ import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
@ -123,7 +122,7 @@ public class Main {
|
||||
}
|
||||
|
||||
// open file channel and lock
|
||||
FileChannel logChannel = new FileOutputStream(logFile, true).getChannel();
|
||||
FileChannel logChannel = FileChannel.open(logFile.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.APPEND);
|
||||
if (args.logLock) {
|
||||
System.out.println("Locking " + logFile);
|
||||
logChannel.lock();
|
||||
@ -446,8 +445,7 @@ public class Main {
|
||||
final File lockFile = new File(cache, ".lock");
|
||||
boolean isNewCache = !lockFile.exists();
|
||||
|
||||
final RandomAccessFile handle = new RandomAccessFile(lockFile, "rw");
|
||||
final FileChannel channel = handle.getChannel();
|
||||
final FileChannel channel = FileChannel.open(lockFile.toPath(), StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE);
|
||||
final FileLock lock = channel.tryLock();
|
||||
|
||||
if (lock != null) {
|
||||
@ -499,7 +497,7 @@ public class Main {
|
||||
// ignore, shutting down anyway
|
||||
}
|
||||
try {
|
||||
handle.close();
|
||||
channel.close();
|
||||
} catch (Exception e) {
|
||||
// ignore, shutting down anyway
|
||||
}
|
||||
@ -511,7 +509,7 @@ public class Main {
|
||||
}
|
||||
|
||||
// try next lock file
|
||||
handle.close();
|
||||
channel.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.WARNING, e.toString(), e);
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
package net.filebot.ui.transfer;
|
||||
|
||||
|
||||
import static net.filebot.Settings.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
|
||||
@ -9,29 +7,25 @@ import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.filebot.util.FileUtilities;
|
||||
import net.filebot.util.TemporaryFolder;
|
||||
|
||||
|
||||
public class ByteBufferTransferable implements Transferable {
|
||||
|
||||
|
||||
protected final Map<String, ByteBuffer> vfs;
|
||||
|
||||
|
||||
private FileTransferable transferable;
|
||||
|
||||
|
||||
public ByteBufferTransferable(Map<String, ByteBuffer> vfs) {
|
||||
this.vfs = vfs;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
|
||||
@ -41,62 +35,52 @@ public class ByteBufferTransferable implements Transferable {
|
||||
if (transferable == null) {
|
||||
transferable = createFileTransferable();
|
||||
}
|
||||
|
||||
|
||||
return transferable.getTransferData(flavor);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
|
||||
|
||||
protected FileTransferable createFileTransferable() throws IOException {
|
||||
// remove invalid characters from file name
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
|
||||
for (Entry<String, ByteBuffer> entry : vfs.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
ByteBuffer data = entry.getValue().duplicate();
|
||||
|
||||
|
||||
// write temporary file
|
||||
files.add(createTemporaryFile(name, data));
|
||||
}
|
||||
|
||||
|
||||
return new FileTransferable(files);
|
||||
}
|
||||
|
||||
|
||||
protected File createTemporaryFile(String name, ByteBuffer data) throws IOException {
|
||||
// remove invalid characters from file name
|
||||
String validFileName = validateFileName(name);
|
||||
|
||||
|
||||
// create new temporary file in TEMP/APP_NAME [UUID]/dnd
|
||||
File temporaryFile = TemporaryFolder.getFolder(getApplicationName()).subFolder("dnd").createFile(validFileName);
|
||||
|
||||
|
||||
// write data to file
|
||||
FileChannel fileChannel = new FileOutputStream(temporaryFile).getChannel();
|
||||
|
||||
try {
|
||||
fileChannel.write(data);
|
||||
} finally {
|
||||
fileChannel.close();
|
||||
}
|
||||
|
||||
FileUtilities.writeFile(data, temporaryFile);
|
||||
|
||||
return temporaryFile;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[] { DataFlavor.javaFileListFlavor, FileTransferable.uriListFlavor };
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return FileTransferable.isFileListFlavor(flavor);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -23,6 +22,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -204,7 +204,7 @@ public final class FileUtilities {
|
||||
}
|
||||
|
||||
public static File writeFile(ByteBuffer data, File destination) throws IOException {
|
||||
try (FileOutputStream stream = new FileOutputStream(destination); FileChannel channel = stream.getChannel()) {
|
||||
try (FileChannel channel = FileChannel.open(destination.toPath(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) {
|
||||
channel.write(data);
|
||||
}
|
||||
return destination;
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -12,38 +10,30 @@ import java.nio.ByteOrder;
|
||||
import java.nio.LongBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
/**
|
||||
* Hash code is based on Media Player Classic. In natural language it calculates: size + 64bit
|
||||
* checksum of the first and last 64k (even if they overlap because the file is smaller than
|
||||
* 128k).
|
||||
* Hash code is based on Media Player Classic. In natural language it calculates: size + 64bit checksum of the first and last 64k (even if they overlap because the file is smaller than 128k).
|
||||
*/
|
||||
public final class OpenSubtitlesHasher {
|
||||
|
||||
|
||||
/**
|
||||
* Size of the chunks that will be hashed in bytes (64 KB)
|
||||
*/
|
||||
public static final int HASH_CHUNK_SIZE = 64 * 1024;
|
||||
|
||||
|
||||
public static String computeHashNIO(File file) throws IOException {
|
||||
long size = file.length();
|
||||
long chunkSizeForFile = Math.min(HASH_CHUNK_SIZE, size);
|
||||
|
||||
FileChannel fileChannel = new FileInputStream(file).getChannel();
|
||||
|
||||
try {
|
||||
long head = computeHashForChunk(fileChannel.map(MapMode.READ_ONLY, 0, chunkSizeForFile));
|
||||
long tail = computeHashForChunk(fileChannel.map(MapMode.READ_ONLY, Math.max(size - HASH_CHUNK_SIZE, 0), chunkSizeForFile));
|
||||
|
||||
|
||||
try (FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ)) {
|
||||
long head = computeHashForChunk(channel.map(MapMode.READ_ONLY, 0, chunkSizeForFile));
|
||||
long tail = computeHashForChunk(channel.map(MapMode.READ_ONLY, Math.max(size - HASH_CHUNK_SIZE, 0), chunkSizeForFile));
|
||||
|
||||
return String.format("%016x", size + head + tail);
|
||||
} finally {
|
||||
fileChannel.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String computeHash(File file) throws IOException {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
try {
|
||||
@ -52,44 +42,43 @@ public final class OpenSubtitlesHasher {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String computeHash(InputStream stream, long length) throws IOException {
|
||||
int chunkSizeForFile = (int) Math.min(HASH_CHUNK_SIZE, length);
|
||||
|
||||
|
||||
// buffer that will contain the head and the tail chunk, chunks will overlap if length is smaller than two chunks
|
||||
byte[] chunkBytes = new byte[(int) Math.min(2 * HASH_CHUNK_SIZE, length)];
|
||||
|
||||
|
||||
DataInputStream in = new DataInputStream(stream);
|
||||
|
||||
|
||||
// first chunk
|
||||
in.readFully(chunkBytes, 0, chunkSizeForFile);
|
||||
|
||||
|
||||
long position = chunkSizeForFile;
|
||||
long tailChunkPosition = length - chunkSizeForFile;
|
||||
|
||||
|
||||
// seek to position of the tail chunk, or not at all if length is smaller than two chunks
|
||||
while (position < tailChunkPosition && (position += in.skip(tailChunkPosition - position)) >= 0);
|
||||
|
||||
while (position < tailChunkPosition && (position += in.skip(tailChunkPosition - position)) >= 0) {
|
||||
}
|
||||
|
||||
// second chunk, or the rest of the data if length is smaller than two chunks
|
||||
in.readFully(chunkBytes, chunkSizeForFile, chunkBytes.length - chunkSizeForFile);
|
||||
|
||||
|
||||
long head = computeHashForChunk(ByteBuffer.wrap(chunkBytes, 0, chunkSizeForFile));
|
||||
long tail = computeHashForChunk(ByteBuffer.wrap(chunkBytes, chunkBytes.length - chunkSizeForFile, chunkSizeForFile));
|
||||
|
||||
|
||||
return String.format("%016x", length + head + tail);
|
||||
}
|
||||
|
||||
|
||||
private static long computeHashForChunk(ByteBuffer buffer) {
|
||||
LongBuffer longBuffer = buffer.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
|
||||
long hash = 0;
|
||||
|
||||
|
||||
while (longBuffer.hasRemaining()) {
|
||||
hash += longBuffer.get();
|
||||
}
|
||||
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user