mirror of https://github.com/zlatinb/muwire
retry hashing if an internal error happens
parent
cb204a6c79
commit
5365285e73
|
@ -2,7 +2,7 @@ package com.muwire.core.files
|
||||||
|
|
||||||
import com.muwire.core.InfoHash
|
import com.muwire.core.InfoHash
|
||||||
import com.muwire.core.util.DataUtil
|
import com.muwire.core.util.DataUtil
|
||||||
|
import groovy.util.logging.Log
|
||||||
import net.i2p.data.Base64
|
import net.i2p.data.Base64
|
||||||
|
|
||||||
import java.nio.MappedByteBuffer
|
import java.nio.MappedByteBuffer
|
||||||
|
@ -11,7 +11,9 @@ import java.nio.channels.FileChannel.MapMode
|
||||||
import java.nio.channels.FileLock
|
import java.nio.channels.FileLock
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.security.NoSuchAlgorithmException
|
import java.security.NoSuchAlgorithmException
|
||||||
|
import java.util.logging.Level
|
||||||
|
|
||||||
|
@Log
|
||||||
class FileHasher {
|
class FileHasher {
|
||||||
|
|
||||||
public static final int MIN_PIECE_SIZE_POW2 = 17
|
public static final int MIN_PIECE_SIZE_POW2 = 17
|
||||||
|
@ -50,34 +52,41 @@ class FileHasher {
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoHash hashFile(File file) {
|
InfoHash hashFile(File file) {
|
||||||
final long length = file.length()
|
while(true) {
|
||||||
final long size = 0x1L << getPieceSize(length)
|
try {
|
||||||
int numPieces = (length / size).toInteger()
|
final long length = file.length()
|
||||||
if (numPieces * size < length)
|
final long size = 0x1L << getPieceSize(length)
|
||||||
numPieces++
|
int numPieces = (length / size).toInteger()
|
||||||
|
if (numPieces * size < length)
|
||||||
|
numPieces++
|
||||||
|
|
||||||
def output = new ByteArrayOutputStream()
|
def output = new ByteArrayOutputStream()
|
||||||
RandomAccessFile raf = new RandomAccessFile(file, "r")
|
RandomAccessFile raf = new RandomAccessFile(file, "r")
|
||||||
MappedByteBuffer buf = null
|
MappedByteBuffer buf = null
|
||||||
|
|
||||||
try(FileLock lock = raf.getChannel().lock(0, Long.MAX_VALUE, true)) {
|
try (FileLock lock = raf.getChannel().lock(0, Long.MAX_VALUE, true)) {
|
||||||
for (int i = 0; i < numPieces - 1; i++) {
|
for (int i = 0; i < numPieces - 1; i++) {
|
||||||
buf = raf.getChannel().map(MapMode.READ_ONLY, size * i, size.toInteger())
|
buf = raf.getChannel().map(MapMode.READ_ONLY, size * i, size.toInteger())
|
||||||
digest.update buf
|
digest.update buf
|
||||||
DataUtil.tryUnmap(buf)
|
DataUtil.tryUnmap(buf)
|
||||||
output.write(digest.digest(), 0, 32)
|
output.write(digest.digest(), 0, 32)
|
||||||
|
}
|
||||||
|
long lastPieceLength = length - (numPieces - 1) * size
|
||||||
|
buf = raf.getChannel().map(MapMode.READ_ONLY, length - lastPieceLength, lastPieceLength.toInteger())
|
||||||
|
digest.update buf
|
||||||
|
output.write(digest.digest(), 0, 32)
|
||||||
|
} finally {
|
||||||
|
raf.close()
|
||||||
|
DataUtil.tryUnmap(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] hashList = output.toByteArray()
|
||||||
|
return InfoHash.fromHashList(hashList)
|
||||||
|
} catch (InternalError bad) {
|
||||||
|
// nothing we can but try again. Happens on jre 18.0.1
|
||||||
|
log.log(Level.SEVERE,"internal error while hashing", bad)
|
||||||
}
|
}
|
||||||
long lastPieceLength = length - (numPieces - 1) * size
|
|
||||||
buf = raf.getChannel().map(MapMode.READ_ONLY, length - lastPieceLength, lastPieceLength.toInteger())
|
|
||||||
digest.update buf
|
|
||||||
output.write(digest.digest(), 0, 32)
|
|
||||||
} finally {
|
|
||||||
raf.close()
|
|
||||||
DataUtil.tryUnmap(buf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte [] hashList = output.toByteArray()
|
|
||||||
InfoHash.fromHashList(hashList)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
Loading…
Reference in New Issue