如何在Java中生成.torrent?

Kri*_*ves 7 java api bittorrent

我想用Java生成一个.torrent文件,但是我不想要一个像抓取跟踪器,播种等任何东西的大API.这只适用于生成元数据的客户端.有哪些轻量级解决方案 我只生成一个.zip文件的.torrent.

谢谢!

Ale*_*min 22

我已经把这个自包含的Java代码放在一起,用一个文件准备一个.torrent文件.

.torrent文件是通过调用createTorrent().torrent文件的名称,共享文件的名称和跟踪器URL来创建的.

createTorrent()用于使用Java的类hashPieces()散列文件片段MessageDigest.然后createTorrent()准备一个包含torrent元数据的元信息字典.然后使用这些方法以适当的bencode格式序列化该字典encode*()并保存在.torrent文件中.

有关详细信息,请参阅BitTorrent规范.

public class Torrent {
    private static void encodeObject(Object o, OutputStream out) throws IOException {
        if (o instanceof String)
            encodeString((String)o, out);
        else if (o instanceof Map)
            encodeMap((Map)o, out);
        else if (o instanceof byte[])
            encodeBytes((byte[])o, out);
        else if (o instanceof Number)
            encodeLong(((Number) o).longValue(), out);
        else
            throw new Error("Unencodable type");
    }
    private static void encodeLong(long value, OutputStream out) throws IOException {
        out.write('i');
        out.write(Long.toString(value).getBytes("US-ASCII"));
        out.write('e');
    }
    private static void encodeBytes(byte[] bytes, OutputStream out) throws IOException {
        out.write(Integer.toString(bytes.length).getBytes("US-ASCII"));
        out.write(':');
        out.write(bytes);
    }
    private static void encodeString(String str, OutputStream out) throws IOException {
        encodeBytes(str.getBytes("UTF-8"), out);
    }
    private static void encodeMap(Map<String,Object> map, OutputStream out) throws IOException{
        // Sort the map. A generic encoder should sort by key bytes
        SortedMap<String,Object> sortedMap = new TreeMap<String, Object>(map);
        out.write('d');
        for (Entry<String, Object> e : sortedMap.entrySet()) {
            encodeString(e.getKey(), out);
            encodeObject(e.getValue(), out);
        }
        out.write('e');
    }
    private static byte[] hashPieces(File file, int pieceLength) throws IOException {
        MessageDigest sha1;
        try {
            sha1 = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
            throw new Error("SHA1 not supported");
        }
        InputStream in = new FileInputStream(file);
        ByteArrayOutputStream pieces = new ByteArrayOutputStream();
        byte[] bytes = new byte[pieceLength];
        int pieceByteCount  = 0, readCount = in.read(bytes, 0, pieceLength);
        while (readCount != -1) {
            pieceByteCount += readCount;
            sha1.update(bytes, 0, readCount);
            if (pieceByteCount == pieceLength) {
                pieceByteCount = 0;
                pieces.write(sha1.digest());
            }
            readCount = in.read(bytes, 0, pieceLength-pieceByteCount);
        }
        in.close();
        if (pieceByteCount > 0)
            pieces.write(sha1.digest());
        return pieces.toByteArray();
    }
    public static void createTorrent(File file, File sharedFile, String announceURL) throws IOException {
        final int pieceLength = 512*1024;
        Map<String,Object> info = new HashMap<String,Object>();
        info.put("name", sharedFile.getName());
        info.put("length", sharedFile.length());
        info.put("piece length", pieceLength);
        info.put("pieces", hashPieces(sharedFile, pieceLength));
        Map<String,Object> metainfo = new HashMap<String,Object>();
        metainfo.put("announce", announceURL);
        metainfo.put("info", info);
        OutputStream out = new FileOutputStream(file);
        encodeMap(metainfo, out);
        out.close();
    }

    public static void main(String[] args) throws Exception {
        createTorrent(new File("C:/x.torrent"), new File("C:/file"), "http://example.com/announce");
    }
}
Run Code Online (Sandbox Code Playgroud)

代码编辑:使其更紧凑,修复方法可见性,在适当的地方使用字符文字,使用instanceof Number.最近使用块I/O读取文件,因为我试图将它用于实际,而字节I/O只是很慢,


Cra*_*der 10

我将从Java Bittorrent API开始.罐子大约70Kb,但你可以通过删除创建种子所不需要的类来剥离它.SDK有一个示例ExampleCreateTorrent.java,说明如何完全按照您的需要进行操作.

您还可以了解它是如何在开源Java客户端(如Azureus)中实现的.