How can I generate .torrent in Java?

I want to generate a .torrent file in Java, but I don't want the large API to do something like scrambling, sorting, etc. It is just for the client that generates metadata. What easy solutions exist? I only generate .torrent single .zip file.

Thanks!

+7
java api bittorrent
source share
2 answers

I put together this self-contained piece of Java code to prepare a .torrent file with a single file.

A .torrent file is created by calling createTorrent() , passing the name of the .torrent file, the name of the shared file, and the tracker URL.

createTorrent() uses hashPieces() to hash fragments of a file using the Java MessageDigest class. Then createTorrent() prepares a meta-information dictionary containing torrent metadata. This dictionary is then serialized in its own bencode format using the encode*() methods and saved in the .torrent file.

See the BitTorrent Specification for more details.

 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"); } } 

Code editing: Make it a little more compact, consolidate the visibility of methods, use character literals where necessary, use instanceof Number . And just recently I read a file using block I / O, because I'm trying to use it for real and byte I / O just slowly,

+22
source share

I would start with the Java Bittorrent API . The jar is about 70Kb, but you can possibly delete it by deleting classes that are not necessary for creating torrents. There is a sample ExampleCreateTorrent.java in the SDK that illustrates how to do exactly what you need.

You can also see how it is implemented in open source Java clients such as Azureus.

+10
source share

All Articles