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

📄 fileutil.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
 /*
 * Created on Oct 10, 2003
 * Modified Apr 14, 2004 by Alon Rohter
 * Copyright (C) 2003, 2004, 2005, 2006 Aelitis, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * AELITIS, SAS au capital de 46,603.30 euros
 * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
 * 
 */

package org.gudy.azureus2.core3.util;

import java.io.*;
import java.net.URI;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.platform.PlatformManager;
import org.gudy.azureus2.platform.PlatformManagerCapabilities;
import org.gudy.azureus2.platform.PlatformManagerFactory;
import org.gudy.azureus2.plugins.platform.PlatformManagerException;

import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.AzureusCoreFactory;
import com.aelitis.azureus.core.AzureusCoreOperation;
import com.aelitis.azureus.core.AzureusCoreOperationTask;

/**
 * File utility class.
 */
public class FileUtil {
	private static final LogIDs LOGID = LogIDs.CORE;
  public static final String DIR_SEP = System.getProperty("file.separator");
  
  private static final int	RESERVED_FILE_HANDLE_COUNT	= 4;
	
  private static List		reserved_file_handles 	= new ArrayList();
  private static AEMonitor	class_mon				= new AEMonitor( "FileUtil:class" );

  public static boolean isAncestorOf(File parent, File child) {
	  parent = canonise(parent);
	  child = canonise(child);
	  if (parent.equals(child)) {return true;}
	  String parent_s = parent.getPath();
	  String child_s = child.getPath();
	  if (parent_s.charAt(parent_s.length()-1) != File.separatorChar) {
		  parent_s += File.separatorChar;
	  }
	  return child_s.startsWith(parent_s);
  }
  
  public static File canonise(File file) {
	  try {return file.getCanonicalFile();}
	  catch (IOException ioe) {return file;}
  }
  
  public static String getCanonicalFileName(String filename) {
    // Sometimes Windows use filename in 8.3 form and cannot
    // match .torrent extension. To solve this, canonical path
    // is used to get back the long form

    String canonicalFileName = filename;
    try {
      canonicalFileName = new File(filename).getCanonicalPath();
    }
    catch (IOException ignore) {}
    return canonicalFileName;
  }

  
  public static File getUserFile(String filename) {
    return new File(SystemProperties.getUserPath(), filename);
  }
  
  public static File getApplicationFile(String filename) {
      
    String path = SystemProperties.getApplicationPath();
      
      if(Constants.isOSX) {
        path = path + "/" + SystemProperties.getApplicationName() + ".app/Contents/";
      }
      
      return new File(path, filename);
  }
  
  
  
  /**
   * Deletes the given dir and all files/dirs underneath
   */
  public static void recursiveDelete(File f) {
    String defSaveDir = COConfigurationManager.getStringParameter("Default save path", "");
    String moveToDir = COConfigurationManager.getStringParameter("Completed Files Directory", "");
    
    try{
  	  moveToDir = new File(moveToDir).getCanonicalPath();
    }catch( Throwable e ){
    }
    try{
    	defSaveDir = new File(defSaveDir).getCanonicalPath();
    }catch( Throwable e ){
    }
    
    try {

      if (f.getCanonicalPath().equals(moveToDir)) {
        System.out.println("FileUtil::recursiveDelete:: not allowed to delete the MoveTo dir !");
        return;
      }
      if (f.getCanonicalPath().equals(defSaveDir)) {
        System.out.println("FileUtil::recursiveDelete:: not allowed to delete the default data dir !");
        return;
      }
      
      if (f.isDirectory()) {
        File[] files = f.listFiles();
        for (int i = 0; i < files.length; i++) {
          recursiveDelete(files[i]);
        }
        f.delete();
      }
      else {
        f.delete();
      }
    } catch (Exception ignore) {/*ignore*/}
  }
  
  public static long
  getFileOrDirectorySize(
  	File		file )
  {
  	if ( file.isFile()){
  		
  		return( file.length());
  		
  	}else{
  		
  		long	res = 0; 
  			
  		File[] files = file.listFiles();
  		
  		if ( files != null ){
  			
  			for (int i=0;i<files.length;i++){
  				
  				res += getFileOrDirectorySize( files[i] );
  			}
  		}
  		
  		return( res );
  	}
  }
  
  protected static void 
  recursiveEmptyDirDelete(
  	File	f,
	Set		ignore_set,
	boolean	log_warnings ) 
  {
     try {
      String defSaveDir 	= COConfigurationManager.getStringParameter("Default save path", "");
      String moveToDir 		= COConfigurationManager.getStringParameter("Completed Files Directory", "");
        
      if ( defSaveDir.trim().length() > 0 ){
      	
      	defSaveDir = new File(defSaveDir).getCanonicalPath();
      }

      if ( moveToDir.trim().length() > 0 ){
      	
      	moveToDir = new File(moveToDir).getCanonicalPath();
      }
      
      if ( f.isDirectory()){
      	
        File[] files = f.listFiles();
        
        if ( files == null ){
        	
        	if (log_warnings ){
        		Debug.out("Empty folder delete:  failed to list contents of directory " + f );
        	}
          	 
          	return;
        }
        
        for (int i = 0; i < files.length; i++) {
        	
        	File	x = files[i];
        	
        	if ( x.isDirectory()){
        		
        		recursiveEmptyDirDelete(files[i],ignore_set,log_warnings);
        		
        	}else{
        		
        		if ( ignore_set.contains( x.getName().toLowerCase())){
        			
        			if ( !x.delete()){
        				
        				if ( log_warnings ){
        					Debug.out("Empty folder delete: failed to delete file " + x );
        				}
        			}
        		}
        	}
        }

        if (f.getCanonicalPath().equals(moveToDir)) {
        	
        	if ( log_warnings ){
        		Debug.out("Empty folder delete:  not allowed to delete the MoveTo dir !");
        	}
          
          return;
        }
        
        if (f.getCanonicalPath().equals(defSaveDir)) {
        	
        	if ( log_warnings ){
        		Debug.out("Empty folder delete:  not allowed to delete the default data dir !");
        	}
          
          return;
        }

        if (f.listFiles().length == 0) {
        	
          if ( !f.delete()){
          	
        	  if ( log_warnings ){
        		  Debug.out("Empty folder delete:  failed to delete directory " + f );
        	  }
          }
        }else{
        	if ( log_warnings ){
        		Debug.out("Empty folder delete: "+f.listFiles().length+" file(s)/folder(s) still in " + f + ". Not removing.");
        	}
        }
      }

    } catch (Exception e) { Debug.out(e.toString()); }
  }
  
  public static String
  convertOSSpecificChars(
  	String	file_name_in )
  {
  		// this rule originally from DiskManager
 
  	char[]	chars = file_name_in.toCharArray();
  	
  	for (int i=0;i<chars.length;i++){
  		
  		if ( chars[i] == '"' ){
  			
  			chars[i] = '\'';
  		}
  	}
  	
  	if ( !Constants.isOSX ){
  		
  		if ( Constants.isWindows ){
  			
  				//  this rule originally from DiskManager

	 		// The definitive list of characters permitted for Windows is defined here:
	 		// http://support.microsoft.com/kb/q120138/
  			String not_allowed = "\\/:?*<>"; 
  		 	for (int i=0;i<chars.length;i++){
  		 		if (not_allowed.indexOf(chars[i]) != -1) {
  		  			chars[i] = '_';
  		  		}
  		  	}
  		}
  		
  			// '/' is valid in mac file names, replace with space
  			// so it seems are cr/lf
  		
	 	for (int i=0;i<chars.length;i++){
		 		
			char	c = chars[i];
				
			if ( c == '/' || c == '\r' || c == '\n'  ){
		  			
				chars[i] = ' ';
			}
		}
  	}

  	String	file_name_out = new String(chars);
  	
	try{
		
			// mac file names can end in space - fix this up by getting
			// the canonical form which removes this on Windows
		
			// however, for soem reason getCanonicalFile can generate high CPU usage on some user's systems
			// in  java.io.Win32FileSystem.canonicalize
			// so changing this to only be used on non-windows
		
		if ( Constants.isWindows ){
			
			while( file_name_out.endsWith( " " )){
				
				file_name_out = file_name_out.substring(0,file_name_out.length()-1);
			}
			
		}else{
			
			String str = new File(file_name_out).getCanonicalFile().toString();
		
			int	p = str.lastIndexOf( File.separator );
			
			file_name_out = str.substring(p+1);
		}
		
	}catch( Throwable e ){
		// ho hum, carry on, it'll fail later
		//e.printStackTrace();
	}
	
	//System.out.println( "convertOSSpecificChars: " + file_name_in + " ->" + file_name_out );
	
	return( file_name_out );
  }
  
  public static void
  writeResilientConfigFile(
  	String		file_name,
	Map			data )
  {
	  File parent_dir = new File(SystemProperties.getUserPath());
	  
	  boolean use_backups = COConfigurationManager.getBooleanParameter("Use Config File Backups" );

	  writeResilientFile( parent_dir, file_name, data, use_backups );
  }
  
  public static void
  writeResilientFile(
	File		file,
	Map			data )
  {
	  writeResilientFile( file.getParentFile(), file.getName(), data, false );
  }
  
  public static void
  writeResilientFile(
    File		parent_dir,
  	String		file_name,
	Map			data,
	boolean		use_backup )
  {	  
	  if ( use_backup ){
		  
		  File	originator = new File( parent_dir, file_name );
		  
		  if ( originator.exists()){
			  
			  backupFile( originator, true );
		  }
	  }
	  
	  writeResilientFile( parent_dir, file_name, data );
  }
  
  	// synchronise it to prevent concurrent attempts to write the same file
  
  private static void
  writeResilientFile(
	File		parent_dir,
  	String		file_name,
	Map			data )
  {
  	try{
  		class_mon.enter();
  	
	  	try{
	  		getReservedFileHandles();
	      File temp = new File(  parent_dir, file_name + ".saving");
		    BufferedOutputStream	baos = null;
		    
		    try{
		    	byte[] encoded_data = BEncoder.encode(data);
		    	FileOutputStream tempOS = new FileOutputStream( temp, false );
		    	baos = new BufferedOutputStream( tempOS, 8192 );
		    	baos.write( encoded_data );
		    	baos.flush();
		    	tempOS.getFD().sync();
	        baos.close();
	        baos = null;
	           
	        //only use newly saved file if it got this far, i.e. it saved successfully
	        if ( temp.length() > 1L ) {
	        	File file = new File( parent_dir, file_name );
	        	if ( file.exists() ){
	        		file.delete();
	        	}
	        	temp.renameTo( file );
	        }
	
		    }catch (Exception e) {
		    	Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "Save of '"
							+ file_name + "' fails", e));
		    	
		    }finally{
		    	
		    	try {
		    		if (baos != null){
		    			
		    			baos.close();
		    		}
		    	}catch( Exception e){
		    		Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "Save of '"
								+ file_name + "' fails", e)); 
		    	}
		    }
	  	}finally{
	  		
	  		releaseReservedFileHandles();
	  	}
  	}finally{
  		
  		class_mon.exit();
  	}
  }
  
	public static Map
	readResilientConfigFile(
		String		file_name )
	{
 		File parent_dir = new File(SystemProperties.getUserPath());
  		
 		boolean use_backups = COConfigurationManager.getBooleanParameter("Use Config File Backups" );

 		return( readResilientFile( parent_dir, file_name, use_backups ));
	}
	
	public static Map
	readResilientConfigFile(
		String		file_name,
		boolean		use_backups )
	{
 		File parent_dir = new File(SystemProperties.getUserPath());
  		
 		if ( !use_backups ){
 			
 				// override if a backup file exists. This is needed to cope with backups
 				// of the main config file itself as when boostrapping we can't get the
 				// "use backups" 
 			
 			if ( new File( parent_dir, file_name + ".bak").exists()){
 				
 				use_backups = true;
 			}
 		}
 		
 		return( readResilientFile( parent_dir, file_name, use_backups ));
	}
	
	public static Map
	readResilientFile(
		File		file )
	{
		return( readResilientFile( file.getParentFile(),file.getName(),false));
	}
	
 	public static Map
	readResilientFile(
		File		parent_dir,
		String		file_name,
		boolean		use_backup )
 	{
		File	backup_file = new File( parent_dir, file_name + ".bak" );
		 
 		if ( use_backup ){	
			
 			use_backup = backup_file.exists();
 		}
 			
 			// if we've got a backup, don't attempt recovery here as the .bak file may be
 			// fully OK
 		
 		Map	res = readResilientFileSupport( parent_dir, file_name, !use_backup );
 		
 		if ( res == null && use_backup ){
 				
 				// try backup without recovery
 			
 		 	res = readResilientFileSupport( parent_dir, file_name + ".bak", false );
 		 		
	 		if ( res != null ){
	 			
	 			Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_WARNING,

⌨️ 快捷键说明

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