📄 diskmanagerimpl.java
字号:
}
}
}
if ( getState() == DiskManager.READY ){
if ( checking ){
// we've interrupted a "recheck on complete" - clear the resume data so it rechecks on
// next start up
resume_handler.clearResumeData();
}else{
try{
dumpResumeDataToDisk(true, false);
}catch( Exception e ){
setFailed( "Resume data save fails: " + Debug.getNestedExceptionMessage(e));
}
}
}
saveState();
// can't be used after a stop so we might as well clear down the listeners
listeners.clear();
}
public boolean
filesExist()
{
return( filesExist( download_manager.getAbsoluteSaveLocation().getParent()));
}
protected boolean
filesExist(
String root_dir )
{
if ( !torrent.isSimpleTorrent()){
root_dir += File.separator + download_manager.getAbsoluteSaveLocation().getName();
}
if ( !root_dir.endsWith( File.separator )){
root_dir += File.separator;
}
// System.out.println( "root dir = " + root_dir_file );
DMPieceMapperFile[] pm_files = piece_mapper.getFiles();
String[] storage_types = getStorageTypes();
for (int i = 0; i < pm_files.length; i++) {
DMPieceMapperFile pm_info = pm_files[i];
File relative_file = pm_info.getDataFile();
long target_length = pm_info.getLength();
// use the cache file to ascertain length in case the caching/writing algorithm
// fiddles with the real length
// Unfortunately we may be called here BEFORE the disk manager has been
// started and hence BEFORE the file info has been setup...
// Maybe one day we could allocate the file info earlier. However, if we do
// this then we'll need to handle the "already moved" stuff too...
DiskManagerFileInfoImpl file_info = pm_info.getFileInfo();
boolean close_it = false;
try{
if ( file_info == null ){
boolean linear = storage_types[i].equals("L");
file_info = new DiskManagerFileInfoImpl(
this,
new File( root_dir + relative_file.toString()),
i,
pm_info.getTorrentFile(),
linear );
close_it = true;
}
try{
CacheFile cache_file = file_info.getCacheFile();
File data_file = file_info.getFile(true);
if ( !cache_file.exists()){
// look for something sensible to report
File current = data_file;
while( !current.exists()){
File parent = current.getParentFile();
if ( parent == null ){
break;
}else if ( !parent.exists()){
current = parent;
}else{
if ( parent.isDirectory()){
errorMessage = current.toString() + " not found.";
}else{
errorMessage = parent.toString() + " is not a directory.";
}
return( false );
}
}
errorMessage = data_file.toString() + " not found.";
return false;
}
// only test for too big as if incremental creation selected
// then too small is OK
long existing_length = file_info.getCacheFile().getLength();
if ( existing_length > target_length ){
if ( COConfigurationManager.getBooleanParameter("File.truncate.if.too.large")){
file_info.setAccessMode( DiskManagerFileInfo.WRITE );
file_info.getCacheFile().setLength( target_length );
Debug.out( "Existing data file length too large [" +existing_length+ ">" +target_length+ "]: " + data_file.getAbsolutePath() + ", truncating" );
}else{
errorMessage = "Existing data file length too large [" +existing_length+ ">" +target_length+ "]: " + data_file.getAbsolutePath();
return false;
}
}
}finally{
if ( close_it ){
file_info.getCacheFile().close();
}
}
}catch( Throwable e ){
errorMessage = Debug.getNestedExceptionMessage(e) + " (filesExist:" + relative_file.toString() + ")";
return( false );
}
}
return true;
}
private int
allocateFiles()
{
DMPieceMapperFile[] pm_files = piece_mapper.getFiles();
DiskManagerFileInfoImpl[] allocated_files = new DiskManagerFileInfoImpl[pm_files.length];
try{
allocation_scheduler.register( this );
setState( ALLOCATING );
allocated = 0;
int numNewFiles = 0;
String root_dir = download_manager.getAbsoluteSaveLocation().getParent();
if ( !torrent.isSimpleTorrent()){
root_dir += File.separator + download_manager.getAbsoluteSaveLocation().getName();
}
root_dir += File.separator;
String[] storage_types = getStorageTypes();
for ( int i=0;i<pm_files.length;i++ ){
final DMPieceMapperFile pm_info = pm_files[i];
final long target_length = pm_info.getLength();
File relative_data_file = pm_info.getDataFile();
DiskManagerFileInfoImpl fileInfo;
try{
boolean linear = storage_types[i].equals("L");
fileInfo = new DiskManagerFileInfoImpl(
this,
new File( root_dir + relative_data_file.toString()),
i,
pm_info.getTorrentFile(),
linear );
allocated_files[i] = fileInfo;
pm_info.setFileInfo( fileInfo );
}catch ( CacheFileManagerException e ){
this.errorMessage = Debug.getNestedExceptionMessage(e) + " (allocateFiles:" + relative_data_file.toString() + ")";
setState( FAULTY );
return( -1 );
}
CacheFile cache_file = fileInfo.getCacheFile();
File data_file = fileInfo.getFile(true);
String data_file_name = data_file.getName();
int separator = data_file_name.lastIndexOf(".");
if ( separator == -1 ){
separator = 0;
}
fileInfo.setExtension(data_file_name.substring(separator));
//Added for Feature Request
//[ 807483 ] Prioritize .nfo files in new torrents
//Implemented a more general way of dealing with it.
String extensions = COConfigurationManager.getStringParameter("priorityExtensions","");
if(!extensions.equals("")) {
boolean bIgnoreCase = COConfigurationManager.getBooleanParameter("priorityExtensionsIgnoreCase");
StringTokenizer st = new StringTokenizer(extensions,";");
while(st.hasMoreTokens()) {
String extension = st.nextToken();
extension = extension.trim();
if(!extension.startsWith("."))
extension = "." + extension;
boolean bHighPriority = (bIgnoreCase) ?
fileInfo.getExtension().equalsIgnoreCase(extension) :
fileInfo.getExtension().equals(extension);
if (bHighPriority)
fileInfo.setPriority(true);
}
}
fileInfo.setLength(target_length);
fileInfo.setDownloaded(0);
if ( cache_file.exists() ){
try {
//make sure the existing file length isn't too large
long existing_length = fileInfo.getCacheFile().getLength();
if( existing_length > target_length ){
if ( COConfigurationManager.getBooleanParameter("File.truncate.if.too.large")){
fileInfo.setAccessMode( DiskManagerFileInfo.WRITE );
cache_file.setLength( target_length );
Debug.out( "Existing data file length too large [" +existing_length+ ">" +target_length+ "]: " +data_file.getAbsolutePath() + ", truncating" );
}else{
this.errorMessage = "Existing data file length too large [" +existing_length+ ">" +target_length+ "]: " + data_file.getAbsolutePath();
setState( FAULTY );
return( -1 );
}
}
fileInfo.setAccessMode( DiskManagerFileInfo.READ );
}catch (CacheFileManagerException e) {
this.errorMessage = Debug.getNestedExceptionMessage(e) +
" (allocateFiles existing:" + data_file.getAbsolutePath() + ")";
setState( FAULTY );
return( -1 );
}
allocated += target_length;
}else{ //we need to allocate it
//make sure it hasn't previously been allocated
if ( download_manager.isDataAlreadyAllocated() ){
this.errorMessage = "Data file missing: " + data_file.getAbsolutePath();
setState( FAULTY );
return( -1 );
}
while( started ){
if ( allocation_scheduler.getPermission( this )){
break;
}
}
if ( !started ){
// allocation interrupted
return( -1 );
}
try{
fileInfo.setAccessMode( DiskManagerFileInfo.WRITE );
if( COConfigurationManager.getBooleanParameter("Enable incremental file creation") ) {
// do incremental stuff
fileInfo.getCacheFile().setLength( 0 );
}else {
//fully allocate
if( COConfigurationManager.getBooleanParameter("Zero New") ) { //zero fill
if ( !writer.zeroFile( fileInfo, target_length )) {
try{
// failed to zero it, delete it so it gets done next start
fileInfo.getCacheFile().close();
fileInfo.getCacheFile().delete();
}catch( Throwable e ){
}
setState( FAULTY );
return( -1 );
}
}else{
//reserve the full file size with the OS file system
fileInfo.getCacheFile().setLength( target_length );
allocated += target_length;
}
}
}catch ( Exception e ) {
this.errorMessage = Debug.getNestedExceptionMessage(e)
+ " (allocateFiles new:" + data_file.toString() + ")";
setState( FAULTY );
return( -1 );
}
numNewFiles++;
}
}
// make sure that "files" doens't become visible to the rest of the world until all
// entries have been populated
files = allocated_files;
loadFilePriorities();
download_manager.setDataAlreadyAllocated( true );
return( numNewFiles );
}finally{
allocation_scheduler.unregister( this );
// if we failed to do the allocation make sure we close all the files that
// we might have opened
if ( files == null ){
for (int i=0;i<allocated_files.length;i++){
if ( allocated_files[i] != null ){
try{
allocated_files[i].getCacheFile().close();
}catch( Throwable e ){
}
}
}
}
}
}
public DiskAccessController
getDiskAccessController()
{
return( disk_access_controller );
}
public void
enqueueReadRequest(
DiskManagerReadRequest request,
DiskManagerReadRequestListener listener )
{
reader.readBlock( request, listener );
}
public int
getNbPieces()
{
return nbPieces;
}
public int
getPercentDone()
{
return percentDone;
}
public void
setPercentDone(
int num )
{
percentDone = num;
}
public long
getRemaining() {
return remaining;
}
public long
getRemainingExcludingDND()
{
if ( skipped_file_set_changed ){
DiskManagerFileInfoImpl[] current_files = files;
if ( current_files != null ){
skipped_file_set_changed = false;
try{
file_piece_mon.enter();
skipped_file_set_size = 0;
skipped_but_downloaded = 0;
for (int i=0;i<current_files.length;i++){
DiskManagerFileInfoImpl file = current_files[i];
if ( file.isSkipped()){
skipped_file_set_size += file.getLength();
skipped_but_downloaded += file.getDownloaded();
}
}
}finally{
file_piece_mon.exit();
}
}
}
long rem = ( remaining - ( skipped_file_set_size - skipped_but_downloaded ));
if ( rem < 0 ){
rem = 0;
}
return( rem );
}
public long
getAllocated()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -