对种子文件进行解析需要先了解一下种子文件的格式, 然后根据格式进行对应的解析.
一. BT种子文件格式
这里只是简单的介绍一下, 具体信息可以自行google.
BT种子文件使用了一种叫bencoding的编码方法来保存数据。
bencoding现有四种类型的数据:srings(字符串),integers(整数),lists(列表),dictionaries(字典)
字符串:
字符串被如此编码:<字符串长度>:字符串正文.这种表示法没有任何的分界符.
例子:如”8:announce”指”announce”.
整数:
整数被如此编码: i整数值e. 可以为负数,如’i-3e’
例子:’i3e’ 指 3.
列表:
列表是如此被表示的:
<l>Bencode Value<e>
列表可以用来表示多个对象.
列表内容可以包括字符串,整数,字典,甚至列表本身.
例子:’l4:spam4:eggse’ 指 [ “spam”, eggs” ]
字典:
字典是一个一对一的映射.它表示了一个主键(必须为字符串)和一个数据项(可以为任何Bencode值)的关系.字典可以用来表示一个对象的多种属性.
字典是如此被编码:
<d><bencoded string><bencoded element><e>
注意:字典必须根据主键预排序.
二. 对BT文件进行解析
1.首先创建一个对象BtValue来保存bt文件的四种类型的数据
public class BtValue {
//mValue可以是String, int, list或Map
private final Object mValue;
public BtValue(byte[] mValue) {
this.mValue = mValue;
}
public BtValue(String mValue) throws UnsupportedEncodingException {
this.mValue = mValue.getBytes("UTF-8");
}
public BtValue(String mValue, String enc) throws UnsupportedEncodingException {
this.mValue = mValue.getBytes(enc);
}
public BtValue(int mValue) {
this.mValue = mValue;
}
public BtValue(long mValue) {
this.mValue = mValue;
}
public BtValue(Number mValue) {
this.mValue = mValue;
}
public BtValue(List<BtValue> mValue) {
this.mValue = mValue;
}
public BtValue(Map<String, BtValue> mValue) {
this.mValue = mValue;
}
public Object getValue() {
return this.mValue;
}
/**
* 将BtValue作为String返回, 使用UTF-8进行编码
*/
public String getString() throws InvalidBtEncodingException {
return getString("UTF-8");
}
public String getString(String encoding) throws InvalidBtEncodingException {
try {
return new String(getBytes(), encoding);
} catch (ClassCastException e) {
throw new InvalidBtEncodingException(e.toString());
} catch (UnsupportedEncodingException e) {
throw new InternalError(e.toString());
}
}
/**
* 将Btvalue对象作为byte[]数组返回
*/
public byte[] getBytes() throws InvalidBtEncodingException {
try {
return (byte[])mValue;
} catch (ClassCastException e) {
throw new InvalidBtEncodingException(e.toString());
}
}
/**
* 将BtValue对象作为数字返回
*/
public Number getNumber() throws InvalidBtEncodingException {
try {
return (Number)mValue;
} catch (ClassCastException e) {
throw new InvalidBtEncodingException(e.toString());
}
}
/**
* 将BtValue对象作为short返回
*/
public short getShort() throws InvalidBtEncodingException {
return getNumber().shortValue();
}
/**
* 将BtValue对象作为int返回
*/
public int getInt() throws InvalidBtEncodingException {
return getNumber().intValue();
}
/**
* 将BtValue对象作为long返回
*/
public long getLong() throws InvalidBtEncodingException {
return getNumber().longValue();
}
/**
* 将BtValue对象作为List返回
*/
@SuppressWarnings("unchecked")
public List<BtValue> getList() throws InvalidBtEncodingException {
if (mValue instanceof ArrayList) {
return (ArrayList<BtValue>)mValue;
} else {
throw <