⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmfileimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
				raf	= null;
				
				if ( explicit ){
					
					releaseFile();
				}
			}
		}
		
		if ( flush_exception != null ){
			
			throw( flush_exception );
		}
	}
	
	public void
	flush()
	
		throws FMFileManagerException
	{
		file_access.flush();
	}
	
	public void
	delete()
	
		throws FMFileManagerException
	{
		close();
		
		if ( linked_file.exists()){
			
			if ( !linked_file.delete()){
				
				throw( new FMFileManagerException( "Failed to delete '" + linked_file + "'" ));
			}
		}
	}
	
	protected void
	readSupport(
		DirectByteBuffer	buffer,
		long				position )
	
		throws FMFileManagerException
	{
		readSupport(new DirectByteBuffer[]{buffer}, position );
	}
	
	protected void
	readSupport(
		DirectByteBuffer[]	buffers,
		long				position )
	
		throws FMFileManagerException
	{
		file_access.read( raf, buffers, position );
	}
	
	protected void
	writeSupport(
		DirectByteBuffer		buffer,
		long					position )
	
		throws FMFileManagerException
	{
		writeSupport(new DirectByteBuffer[]{buffer}, position );
	}
	
	protected void
	writeSupport(
		DirectByteBuffer[]		buffers,
		long					position )
	
		throws FMFileManagerException
	{
		file_access.write( raf, buffers, position );
	}
	
	protected boolean
	isOpen()
	{
		return( raf != null );
	}
	
		// file reservation is used to manage the possibility of multiple torrents
		// refering to the same file. Initially introduced to stop a common problem
		// whereby different torrents contain the same files - without 
		// this code the torrents could interfere resulting in all sorts of problems
		// The original behavior was to completely prevent the sharing of files.
		// However, better behaviour is to allow sharing of a file as long as only
		// read access is required.
		// we store a list of owners against each canonical file with a boolean "write" marker
	
	private void
	reserveFile()
	
		throws FMFileManagerException
	{
		try{
			file_map_mon.enter();
			
			// System.out.println( "FMFile::reserveFile:" + canonical_path + "("+ owner.getName() + ")" );
			
			List	owners = (List)file_map.get(canonical_path);
			
			if ( owners == null ){
				
				owners = new ArrayList();
				
				file_map.put( canonical_path, owners );				
			}
			
			for (Iterator it=owners.iterator();it.hasNext();){
				
				Object[]	entry = (Object[])it.next();
			
				if ( owner.getName().equals(((FMFileOwner)entry[0]).getName())){
				
						// already present, start off read-access
					
					Debug.out( "reserve file - entry already present" );
					
					entry[1] = new Boolean( false );
					
					return;	
				}
			}
			
			owners.add( new Object[]{ owner, new Boolean( false ), "<reservation>" });
			
		}finally{
			
			file_map_mon.exit();
		}
	}
	
	private void
	reserveAccess(
		String	reason )
	
		throws FMFileManagerException
	{
		try{
			file_map_mon.enter();
			
			// System.out.println( "FMFile::reserveAccess:" + canonical_path + "("+ owner.getName() + ")" + " [" + (access_mode==FM_WRITE?"write":"read") + "]" );
			
			List	owners = (List)file_map.get( canonical_path );
			
			Object[]	my_entry = null;
					
			if ( owners == null ){
				
				Debug.out( "reserveAccess fail" );
				
				throw( new FMFileManagerException( "File '"+canonical_path+"' has not been reserved (no entries), '" + owner.getName()+"'"));
			}
			
			for (Iterator it=owners.iterator();it.hasNext();){
					
				Object[]	entry = (Object[])it.next();
				
				if ( owner.getName().equals(((FMFileOwner)entry[0]).getName())){
					
					my_entry	= entry;
				}
			}				
			
			if ( my_entry == null ){
				
				Debug.out( "reserveAccess fail" );
				
				throw( new FMFileManagerException( "File '"+canonical_path+"' has not been reserved (not found), '" + owner.getName()+"'"));
			}
		
			my_entry[1] = new Boolean( access_mode==FM_WRITE );
			my_entry[2] = reason;
			
			int	read_access 		= 0;
			int write_access		= 0;
			int	write_access_lax	= 0;
			
			TOTorrentFile	my_torrent_file = owner.getTorrentFile();
			
			String	users = "";
				
			for (Iterator it=owners.iterator();it.hasNext();){
				
				Object[]	entry = (Object[])it.next();
					
				FMFileOwner	this_owner = (FMFileOwner)entry[0];
				
				if (((Boolean)entry[1]).booleanValue()){
										
					write_access++;
					
					TOTorrentFile this_tf = this_owner.getTorrentFile();
					
					if ( my_torrent_file != null && this_tf != null && my_torrent_file.getLength() == this_tf.getLength()){
						
						write_access_lax++;
					}
					
					users += (users.length()==0?"":",") + this_owner.getName() + " [write]";

				}else{
					
					read_access++;
					
					users += (users.length()==0?"":",") + this_owner.getName() + " [read]";
				}
			}

			if ( 	write_access > 1 ||
					( write_access == 1 && read_access > 0 )){
				
					// relax locking if strict is disabled and torrent file is same size
				
				
				if ( !COConfigurationManager.getBooleanParameter( "File.strict.locking" )){
					
					if ( write_access_lax == write_access ){
						
						return;
					}
				}
				
				Debug.out( "reserveAccess fail" );
				
				throw( new FMFileManagerException( "File '"+canonical_path+"' is in use by '" + users +"'"));
			}
			
		}finally{
			
			file_map_mon.exit();
		}
	}
	
	private void
	releaseFile()
	{
		try{
			file_map_mon.enter();
		
			// System.out.println( "FMFile::releaseFile:" + canonical_path + "("+ owner.getName() + ")" );
					
			List	owners = (List)file_map.get( canonical_path );
			
			if ( owners != null ){
				
				for (Iterator it=owners.iterator();it.hasNext();){
					
					Object[]	entry = (Object[])it.next();
					
					if ( owner.getName().equals(((FMFileOwner)entry[0]).getName())){
						
						it.remove();
						
						break;
					}
				}
				
				if ( owners.size() == 0 ){
					
					file_map.remove( canonical_path );
				}
			}
		}finally{
			
			file_map_mon.exit();
		}
	}
	
	protected void
	createDirs(
		File		target )
	
		throws FMFileManagerException
	{
		deleteDirs();
		
		File	parent = target.getParentFile();
		
		if ( !parent.exists()){
			
			List	new_dirs = new ArrayList();
			
			File	current = parent;
			
			while( current != null && !current.exists()){
			
				new_dirs.add( current );
				
				current = current.getParentFile();
			}
			
			created_dirs_leaf	= target;
			created_dirs		= new ArrayList();
			
			if (FileUtil.mkdirs(parent)){
			
				created_dirs_leaf	= target;
				created_dirs		= new_dirs;

				/*
				for (int i=created_dirs.size()-1;i>=0;i--){
					
					System.out.println( "created " + created_dirs.get(i));
				}
				*/
			}else{
        		throw( new FMFileManagerException( "Failed to create parent directory '" + parent + "'"));	
        	}
        }
	}
	
	protected void
	deleteDirs()
	{
		if ( created_dirs_leaf != null ){
			
				// delete any dirs we created if the target file doesn't exist
			
			if ( !created_dirs_leaf.exists()){
				
				Iterator	it = created_dirs.iterator();
					
				while( it.hasNext()){
					
					File	dir = (File)it.next();
					
					if ( dir.exists() && dir.isDirectory()){
						
						File[]	entries = dir.listFiles();
						
						if ( entries == null || entries.length == 0 ){
							
							// System.out.println( "deleted " + dir );
							
							dir.delete();
							
						}else{
							
							break;
						}
					}else{
						
						break;
					}
				}
			}
	
			created_dirs_leaf	= null;
			created_dirs 		= null;
		}
	}
	
	protected String
	getString()
	{
		File cPath = new File(canonical_path);
		String sPaths;
		if (cPath.equals(linked_file))
			sPaths = "can/link=" + Debug.secretFileName(canonical_path);
		else
			sPaths = "can=" + Debug.secretFileName(canonical_path) + ",link="
					+ Debug.secretFileName(linked_file.toString());
		return sPaths + ",raf=" + raf + ",acc=" + access_mode + ",ctrl = "
				+ file_access.getString();
	}
	
	protected static void
	generateEvidence(
		IndentWriter	writer )
	{
		writer.println( "FMFile Reservations" );
		
		try{
			writer.indent();

			try{
				file_map_mon.enter();
			
				Iterator	it = file_map.keySet().iterator();
				
				while( it.hasNext()){
					
					String	key = (String)it.next();
					
					List	owners = (List)file_map.get(key);
					
					Iterator	it2 = owners.iterator();
					
					String	str = "";
						
					while( it2.hasNext()){
						
						Object[]	entry = (Object[])it2.next();

						FMFileOwner	owner 	= (FMFileOwner)entry[0];
						Boolean		write	= (Boolean)entry[1];
						String		reason	= (String)entry[2];
						
						
						str += (str.length()==0?"":", ") + owner.getName() + "[" + (write.booleanValue()?"write":"read")+ "/" + reason + "]";
					}
					

					writer.println( Debug.secretFileName(key) + " -> " + str );
				}
			}finally{
				
				file_map_mon.exit();
			}
			
			FMFileManagerImpl.generateEvidence( writer );
			
		}finally{
			
			writer.exdent();
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -