decoderbencoding.java
来自「一个基于NetBeans平台开发的」· Java 代码 · 共 190 行
JAVA
190 行
package com.sinpool.rivercrescent;
import java.io.*;
import java.util.*;
/**这个类是为了解码Bencoding码的,<br>
*Bencoding码是python(一种面向对象语言)的编码形式,<br>
*因为BitTorrent之父Bram Cohen,<br>
*使用python实现了第一个BT软件,<br>
*所以BT协议中的数据结构,<br>
*都遵循python的规则.<br>
*这也是Bram Cohen所倡导的.<br>
*<br>
*<br>
*<br>
*创建时间:2005.1.19<br>
*@author Sinpool.<br>
*@version 1.0<br>
*<br>
**/
public class DecoderBencoding {
private Hashtable dictionary = new Hashtable();
private Stack stack = new Stack();
private int fileByteLength;
byte[] fileBytes;
/**用来打开需要解码的文件。<br>
*<br>
*@param f 是一个字符串,<br>
* 指出reiverscent元文件的文件名。<br>
*<br>
*/
public void openFile(String f) throws IOException{
String filename = "riverfile\\";
filename += f;
File file = new File(filename);
FileInputStream fis = new FileInputStream(file);
fileBytes = new byte[(int)file.length()];
fis.read(fileBytes,0,(int)file.length());
fis.close(); //如果不管就无法改名
this.fileByteLength = (int)file.length();
}
/**用来解析Bencoding码的具体方法.<br>
*@param fileBytes 参数fileBytes是被解析的信息<br>
*@exception IOException 抛出IOException异常<br>
*@see IOException<br>
**/
public void decoderBencoding() throws IOException{
int index = 0,length_index = 0,path_index = 0;
boolean multiple = false;
boolean name = true;
String key = "",keyName = "",keyValue = "",comparePop = "";
StringBuffer pathValue = new StringBuffer();
StringBuffer keyLength = new StringBuffer();
byte charactor = fileBytes[index++];
charactor = fileBytes[index++];
stack.push("d");
while ( !stack.empty() ){
switch ( charactor ) {
case 'd' : {stack.push("d");break;}
case 'l' : {stack.push("l");break;}
case 'i' : {stack.push("i");break;}
case 'e' : {
comparePop = (String)stack.pop();
if (comparePop.equals("i")){
if ( keyName.equals("length") && multiple){
keyName += ++length_index; //键名是字符串加int
dictionary.put(keyName,new Integer(Integer.parseInt(keyLength.toString())));
keyLength.setLength(0);
name = true;
//System.out.println("keyName: " + keyName);
//System.out.println("keyValue: " + keyLength.toString() );
break;
}
dictionary.put(keyName,new Integer(Integer.parseInt(keyLength.toString())));
}
if (comparePop.equals("l") && keyName.equals("path")){
pathValue.deleteCharAt(pathValue.length()-1);
keyName += ++path_index; //键名是字符串加int
dictionary.put(keyName,pathValue.toString());
//System.out.println("keyValue: " + pathValue.toString() );
pathValue.setLength(0);
}
keyLength.setLength(0);
name = true;
break;
}
default :
{
if ( charactor==':' )
{
int temp = Integer.parseInt( keyLength.toString() );
key = new String(fileBytes,index,temp);
if (name)
{
keyName = new String(key);
name = false;
if(keyName.equals("info") || keyName.equals("files")) name = true;
//System.out.println("keyName: " + keyName);
}
else
{
keyValue = new String(key);
if ( keyName.equals("type") && keyValue.equals("single") ){
dictionary.put("type","single");
}
if ( keyName.equals("type") && keyValue.equals("multiple") ){
multiple = true;
dictionary.put("type","multiple");
}
//块信息的处理
//hash表中第一个块是"0"
//pieces 忠于元文件 是块数*20
//piece 是保存每个字节的字节数组
if ( keyName.equals("pieces") ){
int pieces = temp/20 ;
Byte[] piece;
dictionary.put("pieces",new Integer(pieces*20));
piece = new Byte[pieces*20];
for (int i=0;i<pieces*20;i++){
piece[i] = new Byte(fileBytes[index++]);
}
dictionary.put("piece",piece);
//System.out.println("dictionary." + i + ": " + dictionary.get(String.valueOf(i)));
keyLength.setLength(0);
name = true;
break;
}
//对多文件中path的处理
if ( keyName.equals("path") ){
pathValue.append(keyValue);
pathValue.append("/");
keyLength.setLength(0);
index += temp;
break;
}
dictionary.put(keyName,keyValue);
//System.out.println("keyValue: " + keyValue );
name = true;
}
index += temp;
keyLength.setLength(0);
}
else keyLength.append( (char) charactor );
}
}
if (index != fileByteLength) charactor = fileBytes[index++];
}
dictionary.put("length_index",new Integer(length_index) );
dictionary.put("path_index",new Integer(path_index) );
}
/**<br>
*除了BT协议中的键名之外,<br>
*还有一些辅助键名,<br>
* 比如BitComet中的扩展键名,<br>
* 比如BitTorrent plus中的扩展键名,<br>
* 还有本软件用于准确获得所需信息所扩展的键名:<br>
* type: 用来表示此BT种子文件任务是单文件还是多文件,<br>
* 可能获得的值有两个:single和mutiple;<br>
* length_index:<br>
* 用来表示此BT种子文件有多少文件。<br>
* length数字:<br>
* 数字代表具体某一文件长度;<br>
* 例如:length4表示第四个文件长度;<br>
* 数字从"1"开始,不是从"0"开始。<br>
* path_index:<br>
* 用来表示此BT种子文件有多少path值,<br>
* 每个path代表一个文件;<br>
* path数字:<br>
* 数字代表具体某一path,<br>
* 例如:path4表示第四个文件的path值,<br>
* 这个值只出现在多文件时,<br>
* 此值包括路径和文件名,<br>
* 最上层目录名用键名name的键值所表示;<br>
* 数字从"1"开始,不是从"0"开始。<br>
*<br>
*@return 返回解析后的信息,以Hash表的形式出现<br>
**/
public Hashtable getDictionary(){
return this.dictionary;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?