📄 diskmanagerimpl.java
字号:
return files;
}
private void
constructFilesPieces()
{
for (int i = 0; i < pieceMap.length; i++) {
DMPieceList pieceList = pieceMap[i];
//for each piece
for (int j = 0; j < pieceList.size(); j++) {
//get the piece and the file
DiskManagerFileInfoImpl fileInfo = (pieceList.get(j)).getFile();
if (fileInfo.getFirstPieceNumber() == -1)
fileInfo.setFirstPieceNumber(i);
fileInfo.setNbPieces(fileInfo.getNbPieces() + 1);
}
}
}
public String getErrorMessage() {
return errorMessage;
}
public void
setFailed(
final String reason )
{
/**
* need to run this on a separate thread to avoid deadlock with the stopping
* process - setFailed tends to be called from within the read/write activities
* and stopping these requires this.
*/
new AEThread("DiskManager:setFailed")
{
public void
runSupport()
{
errorMessage = reason;
Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR,
errorMessage));
setState( DiskManager.FAULTY );
DiskManagerImpl.this.stop( false );
}
}.start();
}
public void
setFailed(
final DiskManagerFileInfo file,
final String reason )
{
/**
* need to run this on a separate thread to avoid deadlock with the stopping
* process - setFailed tends to be called from within the read/write activities
* and stopping these requires this.
*/
new AEThread("DiskManager:setFailed")
{
public void
runSupport()
{
errorMessage = reason;
Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR,
errorMessage));
setState( DiskManager.FAULTY );
DiskManagerImpl.this.stop( false );
RDResumeHandler.recheckFile( download_manager, file );
}
}.start();
}
public DMPieceList getPieceList(int piece_number)
{
return (pieceMap[piece_number]);
}
public byte[]
getPieceHash(
int piece_number )
throws TOTorrentException
{
return( torrent.getPieces()[ piece_number ]);
}
public DiskManagerReadRequest
createReadRequest(
int pieceNumber,
int offset,
int length )
{
return( reader.createRequest( pieceNumber, offset, length ));
}
public DiskManagerCheckRequest
createCheckRequest(
int pieceNumber,
Object user_data )
{
return( checker.createRequest( pieceNumber, user_data ));
}
public void
enqueueCompleteRecheckRequest(
DiskManagerCheckRequest request,
DiskManagerCheckRequestListener listener )
{
checker.enqueueCompleteRecheckRequest( request, listener );
}
public void
enqueueCheckRequest(
DiskManagerCheckRequest request,
DiskManagerCheckRequestListener listener )
{
checker.enqueueCheckRequest( request, listener );
}
public int getCompleteRecheckStatus()
{
return ( checker.getCompleteRecheckStatus());
}
public DirectByteBuffer
readBlock(
int pieceNumber,
int offset,
int length )
{
return( reader.readBlock( pieceNumber, offset, length ));
}
public DiskManagerWriteRequest
createWriteRequest(
int pieceNumber,
int offset,
DirectByteBuffer data,
Object user_data )
{
return( writer.createWriteRequest( pieceNumber, offset, data, user_data ));
}
public void
enqueueWriteRequest(
DiskManagerWriteRequest request,
DiskManagerWriteRequestListener listener )
{
writer.writeBlock( request, listener );
}
public boolean
hasOutstandingWriteRequestForPiece(
int piece_number )
{
return( writer.hasOutstandingWriteRequestForPiece( piece_number ));
}
public boolean
checkBlockConsistency(
int pieceNumber,
int offset,
DirectByteBuffer data )
{
if (pieceNumber < 0) {
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR,
"CHECKBLOCK1: pieceNumber=" + pieceNumber + " < 0"));
return false;
}
if (pieceNumber >= this.nbPieces) {
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR,
"CHECKBLOCK1: pieceNumber=" + pieceNumber + " >= this.nbPieces="
+ this.nbPieces));
return false;
}
int length = this.pieceLength;
if (pieceNumber == nbPieces - 1) {
length = this.lastPieceLength;
}
if (offset < 0) {
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR,
"CHECKBLOCK1: offset=" + offset + " < 0"));
return false;
}
if (offset > length) {
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR,
"CHECKBLOCK1: offset=" + offset + " > length=" + length));
return false;
}
int size = data.remaining(DirectByteBuffer.SS_DW);
if (size <= 0) {
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR,
"CHECKBLOCK1: size=" + size + " <= 0"));
return false;
}
if (offset + size > length) {
if (Logger.isEnabled())
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR,
"CHECKBLOCK1: offset=" + offset + " + size=" + size + " > length="
+ length));
return false;
}
return true;
}
public boolean
checkBlockConsistency(
int pieceNumber,
int offset,
int length )
{
return( DiskManagerUtil.checkBlockConsistency(this,pieceNumber, offset, length));
}
public void
saveResumeData(
boolean interim_save )
throws Exception
{
resume_handler.saveResumeData( interim_save );
}
public void downloadEnded() {
moveDownloadFilesWhenEndedOrRemoved(false, true);
}
public void downloadRemoved () {
moveDownloadFilesWhenEndedOrRemoved(true, true);
}
private boolean moveDownloadFilesWhenEndedOrRemoved(final boolean removing, final boolean torrent_file_exists) {
try {
start_stop_mon.enter();
final boolean ending = !removing; // Just a friendly alias.
/**
* It doesn't matter if we set alreadyMoved, but don't end up moving the files.
* This is because we only get called once (when it matters), which is when the
* download has finished. We only want this to apply when the download has finished,
* not if the user restarts the (already completed) download.
*/
if (ending) {
if (this.alreadyMoved) {return false;}
this.alreadyMoved = true;
}
DownloadManagerDefaultPaths.TransferDetails move_details;
if (removing) {
move_details = DownloadManagerDefaultPaths.onRemoval(this.download_manager);
}
else {
move_details = DownloadManagerDefaultPaths.onCompletion(this.download_manager, true);
}
if (move_details == null) {return false;}
//Debug.out("Moving data files: -> " + mdi.location);
moveFiles(move_details.transfer_destination.getPath(), move_details.move_torrent && torrent_file_exists, true);
return true;
}
finally{
start_stop_mon.exit();
if (!removing) {
try{
saveResumeData(false);
}catch( Throwable e ){
setFailed("Resume data save fails: " + Debug.getNestedExceptionMessage(e));
}
}
}
}
public void
moveDataFiles(
File new_parent_dir )
{
moveFiles( new_parent_dir.toString(), false, false );
}
protected void moveFiles(String move_to_dir, boolean move_torrent, boolean change_to_read_only) {
boolean move_files = !isFileDestinationIsItself(move_to_dir);
try {
start_stop_mon.enter();
/**
* The 0 suffix is indicate that these are quite internal, and are
* only intended for use within this method.
*/
boolean files_moved = true;
if (move_files) {
files_moved = moveDataFiles0(move_to_dir, change_to_read_only);
}
if (move_torrent && files_moved) {
moveTorrentFile0(move_to_dir);
}
}
catch(Exception e) {
Debug.printStackTrace(e);
}
finally{
start_stop_mon.exit();
}
}
private boolean isFileDestinationIsItself(String move_to_dir) {
File save_location = download_manager.getAbsoluteSaveLocation();
String move_from_dir = save_location.getParent();
// sanity check - never move a dir into itself
try{
File from_file = new File(move_from_dir).getCanonicalFile();
File to_file = new File(move_to_dir).getCanonicalFile();
save_location = save_location.getCanonicalFile();
move_from_dir = from_file.getPath();
move_to_dir = to_file.getPath();
if (from_file.equals(to_file)){
return true;
}else{
if ( !download_manager.getTorrent().isSimpleTorrent()){
if ( to_file.getPath().startsWith( save_location.getPath())){
String msg = "Target is sub-directory of files";
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
Logger.logTextResource(new LogAlert(LogAlert.REPEATABLE,
LogAlert.AT_ERROR, "DiskManager.alert.movefilefails"),
new String[] {save_location.toString(), msg });
return true;
}
}
}
}catch( Throwable e ){
// carry on
Debug.out(e);
}
return false;
}
private boolean moveDataFiles0(String move_to_dir, boolean change_to_read_only) throws Exception {
File save_location = download_manager.getAbsoluteSaveLocation();
String move_from_dir = save_location.getParent();
// sanity check - never move a dir into itself
try{
File from_file = new File(move_from_dir).getCanonicalFile();
File to_file = new File(move_to_dir).getCanonicalFile();
save_location = save_location.getCanonicalFile();
move_from_dir = from_file.getPath();
move_to_dir = to_file.getPath();
if (from_file.equals(to_file)){
return true;
}else{
if ( !download_manager.getTorrent().isSimpleTorrent()){
if ( to_file.getPath().startsWith( save_location.getPath())){
String msg = "Target is sub-directory of files";
Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
Logger.logTextResource(new LogAlert(LogAlert.REPEATABLE,
LogAlert.AT_ERROR, "DiskManager.alert.movefilefails"),
new String[] {save_location.toString(), msg });
return true;
}
}
}
}catch( Throwable e ){
// carry on
Debug.out(e);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -