Java实现bt文件下载、制作、解析、磁力链接

首先torrent里面肯定携带的有一些信息,所以就需要我们来解析这些信息。

     我们这里做多文件制作torrent,所以首先要针对每一个文件建一个实体类

import java.util.List;
 
public class Info {
	private String name;
    private byte[] pieces;
    private long piecesLength;
    private long length;
    private String md5sum;
    private List<Files> files;
 
    public Info() {
    }
 
	public Info(String name, byte[] pieces, long piecesLength, long length, String md5sum, List<Files> files) {
		super();
		this.name = name;
		this.pieces = pieces;
		this.piecesLength = piecesLength;
		this.length = length;
		this.md5sum = md5sum;
		this.files = files;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public byte[] getPieces() {
		return pieces;
	}
 
	public void setPieces(byte[] pieces) {
		this.pieces = pieces;
	}
 
	public long getPiecesLength() {
		return piecesLength;
	}
 
	public void setPiecesLength(long piecesLength) {
		this.piecesLength = piecesLength;
	}
 
	public long getLength() {
		return length;
	}
 
	public void setLength(long length) {
		this.length = length;
	}
 
	public String getMd5sum() {
		return md5sum;
	}
 
	public void setMd5sum(String md5sum) {
		this.md5sum = md5sum;
	}
 
	public List<Files> getFiles() {
		return files;
	}
 
	public void setFiles(List<Files> files) {
		this.files = files;
	}

而对于每一个File,又存在了一些信息,所以我们针对File建立一个实体类

import java.util.List;
 
public class Files {
	private long length;
    private String md5sum;
    private List<String> path;
 
    public Files() {
    }
    //getter and setter  and tostring
    
	public long getLength() {
		return length;
	}
 
	public Files(long length, String md5sum, List<String> path) {
		super();
		this.length = length;
		this.md5sum = md5sum;
		this.path = path;
	}
 
	public void setLength(long length) {
		this.length = length;
	}
 
	public String getMd5sum() {
		return md5sum;
	}
 
	public void setMd5sum(String md5sum) {
		this.md5sum = md5sum;
	}
 
	public List<String> getPath() {
		return path;
	}
 
	public void setPath(List<String> path) {
		this.path = path;
	}
}

而我们在制作torrent文件时,填写了很多信息,比如要web seeds等等。所以此时也需要一个实体类

import java.util.Arrays;
import java.util.List;
 
import org.jeecgframework.core.util.StringUtil;
 
public class BitTorrentInfo {
	public static List<String> keyList;
    static{
        String[] keys = {"announce", "announce-list", "creation date", "comment", "created by",
                "info", "length", "md5sum", "name", "piece length","pieces", "files", "path"};
        keyList = Arrays.asList(keys);
    }
 
    private String announce;
    private List<String> announceList;
    private long creationDate;
    private String comment;
    private String createBy;
    private Info info;
 
    public BitTorrentInfo() {
    }
 
    //getter and setter  and tostring
 
    public BitTorrentInfo(String announce, List<String> announceList, long creationDate, String comment,
			String createBy, Info info) {
		super();
		this.announce = announce;
		this.announceList = announceList;
		this.creationDate = creationDate;
		this.comment = comment;
		this.createBy = createBy;
		this.info = info;
	}
 
    public static List<String> getKeyList() {
		return keyList;
	}
 
	public static void setKeyList(List<String> keyList) {
		BitTorrentInfo.keyList = keyList;
	}
 
	public String getAnnounce() {
		return announce;
	}
 
	public void setAnnounce(String announce) {
		this.announce = announce;
	}
 
	public List<String> getAnnounceList() {
		return announceList;
	}
 
	public void setAnnounceList(List<String> announceList) {
		this.announceList = announceList;
	}
 
	public long getCreationDate() {
		return creationDate;
	}
 
	public void setCreationDate(long creationDate) {
		this.creationDate = creationDate;
	}
 
	public String getComment() {
		return comment;
	}
 
	public void setComment(String comment) {
		this.comment = comment;
	}
 
	public String getCreateBy() {
		return createBy;
	}
 
	public void setCreateBy(String createBy) {
		this.createBy = createBy;
	}
 
	public Info getInfo() {
		return info;
	}
 
	public void setInfo(Info info) {
		this.info = info;
	}
 
	public void setValue(String key, Object value) throws Exception {
        if(!keyList.contains(key)){
            throw new Exception("not contains this key: " + key);
        }else{
            switch (key){
                case "announce":this.setAnnounce(value.toString());break;
                case "announce-list":this.getAnnounceList().add(value.toString());break;
                case "creation date":
                	if(StringUtil.isNumeric(value.toString())){
                		this.setCreationDate(Long.parseLong(value.toString()));
                	}else{
                		this.setCreationDate(0);
                	}
                	break;
                case "comment":this.setComment(value.toString());break;
                case "created by":this.setCreateBy(value.toString());break;
                case "length":
                    List<Files> filesList1 = this.getInfo().getFiles();
                    if(filesList1 != null){
                        Files files = this.getInfo().getFiles().get(filesList1.size()-1);
                        files.setLength(Long.parseLong(value.toString()));
                    }else {
                        this.getInfo().setLength(Long.parseLong(value.toString()));
                    }
                    break;
                case "md5sum":
                    List<Files> filesList2 = this.getInfo().getFiles();
                    if(filesList2 != null){
                        Files files = this.getInfo().getFiles().get(filesList2.size()-1);
                        files.setMd5sum(value.toString());
                    }else {
                        this.getInfo().setMd5sum(value.toString());
                    }
                    break;
                case "name":
                    this.getInfo().setName(value.toString());
                    break;
                case "piece length":
                    this.getInfo().setPiecesLength(Long.parseLong(value.toString()));
                    break;
                case "pieces":
                	if(StringUtil.isNumeric(value.toString())){
                		this.getInfo().setPieces(null);
                	}else{
                		this.getInfo().setPieces((byte[])value);
                	}
                    break;
                case "path":
                    List<Files> filesList3 = this.getInfo().getFiles();
                    Files files3 = filesList3.get(filesList3.size()-1);
                    files3.getPath().add(value.toString());
                    break;
            }
        }
    }    
}

解析实体类

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
 
public class BitTorrents {
    public static BitTorrentInfo parse(File btFile) throws Exception {
        return new BitTorrents().analyze(new FileInputStream(btFile));
    }
 
    public static BitTorrentInfo parse(String btFilePath) throws Exception {
        return new BitTorrents().analyze(new FileInputStream(btFilePath));
    }
 
    private BitTorrentInfo analyze(InputStream is) throws Exception {
        BitTorrentInfo btInfo = new BitTorrentInfo();
        String key = null;
        StringBuilder strLengthBuilder = new StringBuilder();
        int tempByte;
        while ((tempByte = is.read()) != -1) {
            char temp = (char) tempByte;
            switch (temp) {
                case 'i':
                    StringBuilder itempBuilder = new StringBuilder();
                    char iTemp;
                    while ((iTemp = (char) is.read()) != 'e') {
                        itempBuilder.append(iTemp);
                    }
                    btInfo.setValue(key, itempBuilder.toString());
                    break;
                case '0': case '1': case  '2': case '3': case '4': case  '5': case '6': case '7': case '8': case '9':
                    strLengthBuilder.append(temp);
                    break;
                case ':':
                    int strLen = Integer.parseInt(strLengthBuilder.toString());
                    strLengthBuilder = new StringBuilder();
                    byte[] tempBytes = new byte[strLen];
                    is.read(tempBytes);
                    if (key != null && key.equals("pieces")) {
                        btInfo.setValue(key, tempBytes);
                    } else {
                        String tempStr = new String(tempBytes);
                        if (BitTorrentInfo.keyList.contains(tempStr)) {
                            key = tempStr;
                            if (tempStr.equals("announce-list")) {
                                btInfo.setAnnounceList(new LinkedList<String>());
                            } else if (tempStr.equals("info")) {
                                btInfo.setInfo(new Info());
                            } else if (tempStr.equals("files")) {
                                btInfo.getInfo().setFiles(new LinkedList<Files>());
                                btInfo.getInfo().getFiles().add(new Files());
                            } else if (tempStr.equals("length")) {
                                List<Files> tempFiles = btInfo.getInfo().getFiles();
                                if (tempFiles != null) {
                                    if (tempFiles.isEmpty() || tempFiles.get(tempFiles.size() - 1).getLength() != 0) {
                                        tempFiles.add(new Files());
                                    }
                                }
                            } else if (tempStr.equals("md5sum")) {
                                List<Files> tempFiles = btInfo.getInfo().getFiles();
                                if (tempFiles != null) {
                                    if (tempFiles.isEmpty() || tempFiles.get(tempFiles.size() - 1).getMd5sum() != null) {
                                        tempFiles.add(new Files());
                                    }
                                }
                            } else if (tempStr.equals("path")) {
                                List<Files> tempFilesList = btInfo.getInfo().getFiles();
                                if (tempFilesList.isEmpty()) {
                                    Files files = new Files();
                                    files.setPath(new LinkedList<String>());
                                    tempFilesList.add(files);
                                } else {
                                    Files files = tempFilesList.get(tempFilesList.size() - 1);
                                    if (files.getPath() == null) {
                                        files.setPath(new LinkedList<String>());
                                    }
                                }
                            }
                        } else {
                            btInfo.setValue(key, tempStr);
                        }
                    }
                    break;
            }
        }
        return btInfo;
    }
 
    public static void main(String[] args) throws Exception {
        BitTorrentInfo info=parse("E://xx/xx.torrent");
        System.out.println("信息:"+info.getAnnounce()+"\t"+info.getComment()+"\t"+info.getCreateBy()+"\t"+GetDate.LongConvetDateTime(info.getCreationDate()));
        Info it=info.getInfo();
        System.out.println("信息:"+it.getName()+"\t"+it.getPiecesLength()+"\t"+it.getLength()+"\t"+it.getMd5sum()+"\t"+it.getPieces());
        if(info.getAnnounceList().size()>0){
            for(String str:info.getAnnounceList()){
                System.out.println("信息2:"+str);
            }
        }
        if(it.getFiles().size()>0){
            for(Files file: it.getFiles()){
                System.out.println("信息3:"+file.getLength()+"\t"+file.getMd5sum());
                if(file.getPath().size()>0){
                    for(String str:file.getPath()){
                        System.out.println("信息4:"+str);
                    }
                }
            }
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/p312011150/article/details/81478019