fileutil.java
来自「Azureus is a powerful, full-featured, cr」· Java 代码 · 共 912 行 · 第 1/2 页
JAVA
912 行
/*
* Created on Oct 10, 2003
* Modified Apr 14, 2004 by Alon Rohter
* Copyright (C) 2004 Aelitis, All Rights Reserved.
*
*/
package org.gudy.azureus2.core3.util;
import java.io.*;
import java.net.URI;
import java.util.*;
import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
import org.gudy.azureus2.core3.config.*;
import org.gudy.azureus2.core3.logging.*;
/**
* File utility class.
*/
public class FileUtil {
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 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 + "/Azureus.app/Contents/";
}
return new File(path, filename);
}
public static boolean isTorrentFile(String filename) throws FileNotFoundException, IOException {
File check = new File(filename);
if (!check.exists())
throw new FileNotFoundException("File "+filename+" not found.");
if (!check.canRead())
throw new IOException("File "+filename+" cannot be read.");
if (check.isDirectory())
throw new FileIsADirectoryException("File "+filename+" is a directory.");
try {
TOTorrentFactory.deserialiseFromBEncodedFile(check);
return true;
} catch (Throwable e) {
return false;
}
}
/**
* 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 {
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 );
}
}
/**
* Deletes the given dir and all dirs underneath if empty.
* Don't delete default save path or completed files directory, however,
* allow deletion of their empty subdirectories
* Files defined to be ignored for the sake of torrent creation are automatically deleted
* For example, by default this includes thumbs.db
*/
public static void
recursiveEmptyDirDelete(
File f)
{
Map ignore_map = new HashMap();
String ignore_list = COConfigurationManager.getStringParameter( "File.Torrent.IgnoreFiles", TOTorrent.DEFAULT_IGNORE_FILES );
int pos = 0;
while(true){
int p1 = ignore_list.indexOf( ";", pos );
String bit;
if ( p1 == -1 ){
bit = ignore_list.substring(pos);
}else{
bit = ignore_list.substring( pos, p1 );
pos = p1+1;
}
ignore_map.put(bit.trim().toLowerCase(),"");
if ( p1 == -1 ){
break;
}
}
recursiveEmptyDirDelete( f, ignore_map );
}
private static void
recursiveEmptyDirDelete(
File f,
Map ignore_map )
{
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 ){
Debug.out("FileUtil::recursiveEmptyDirDelete:: failed 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_map);
}else{
if ( ignore_map.get( x.getName().toLowerCase()) != null ){
if ( !x.delete()){
Debug.out("FileUtil::recursiveEmptyDirDelete:: failed to delete file" + x );
}
}
}
}
if (f.getCanonicalPath().equals(moveToDir)) {
Debug.out("FileUtil::recursiveEmptyDirDelete:: not allowed to delete the MoveTo dir !");
return;
}
if (f.getCanonicalPath().equals(defSaveDir)) {
Debug.out("FileUtil::recursiveEmptyDirDelete:: not allowed to delete the default data dir !");
return;
}
if (f.listFiles().length == 0) {
if ( !f.delete()){
Debug.out("FileUtil::recursiveEmptyDirDelete:: failed to delete directory" + f );
}
}else{
Debug.out("FileUtil::recursiveEmptyDirDelete:: "+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
for (int i=0;i<chars.length;i++){
char c = chars[i];
if ( c == '\\' || c == '/' || c == ':' || c == '?' || c == '*' ){
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
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 );
}
// synchronise it to prevent concurrent attempts to write the same file
public static void
writeResilientConfigFile(
String file_name,
Map data )
{
try{
class_mon.enter();
try{
getReservedFileHandles();
File temp = new File( SystemProperties.getUserPath() + file_name + ".saving");
BufferedOutputStream baos = null;
try{
byte[] encoded_data = BEncoder.encode(data);
baos = new BufferedOutputStream( new FileOutputStream( temp, false ), 8192 );
baos.write( encoded_data );
baos.flush();
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( SystemProperties.getUserPath() + file_name );
if ( file.exists() ){
file.delete();
}
temp.renameTo( file );
}
}catch (Exception e) {
LGLogger.logUnrepeatableAlert( "Save of '" + file_name + "' fails", e );
}finally{
try {
if (baos != null){
baos.close();
}
}catch( Exception e){
LGLogger.logUnrepeatableAlert( "Save of '" + file_name + "' fails", e );
}
}
}finally{
releaseReservedFileHandles();
}
}finally{
class_mon.exit();
}
}
// synchronised against writes to make sure we get a consistent view
public static Map
readResilientConfigFile(
String file_name )
{
try{
class_mon.enter();
try{
getReservedFileHandles();
return(readResilientConfigFile( file_name, 0 ));
}catch( Throwable e ){
// just in case something went wrong, make sure we just return a blank
// map
Debug.printStackTrace( e );
return( new HashMap());
}finally{
releaseReservedFileHandles();
}
}finally{
class_mon.exit();
}
}
private static Map
readResilientConfigFile(
String file_name,
int fail_count )
{
// open the file
boolean using_backup = file_name.endsWith(".saving");
File file = new File( SystemProperties.getUserPath() + file_name );
//make sure the file exists and isn't zero-length
if ( (!file.exists()) || file.length() <= 1L ){
if ( using_backup ){
if ( fail_count == 1 ){
// we only alert the user if at least one file was found and failed
// otherwise it could be start of day when neither file exists yet
LGLogger.logUnrepeatableAlert( LGLogger.AT_ERROR,
"Load of '" + file_name + "' fails, no usable file or backup" );
}else{
LGLogger.log( LGLogger.INFORMATION,
"Load of '" + file_name + "' fails, file not found" );
}
return( new HashMap());
}
LGLogger.log("Load of '" + file_name + "' failed, file not found or 0-sized." );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?