⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encoderbencoding.java

📁 一个基于NetBeans平台开发的
💻 JAVA
字号:
package com.sinpool.rivercrescent; 

import java.io.*;
import java.util.*;
import javax.swing.*;
import java.security.*;

import com.sinpool.rivercrescent.interfaces.*;
/**这个类是为了编码Bencoding码的,
 *Bencoding码是python(一种面向对象语言)的编码形式,
 *因为BitTorrent之父Bram Cohen,
 *使用python实现了第一个BT软件,
 *所以BT协议中的数据结构,
 *都遵循python的规则.
 *这也是Bram Cohen所倡导的.
 *
 *创建时间:2005.1.19
 *@author Sinpool.
 *@version 1.0
 *
 **/
 
 public class EncoderBencoding implements Bencoding{
 	private File inFileName = null;
 	private File outFileName = null;
 	private FileInputStream fis   = null;
 	private BufferedInputStream in = null;
 	private FileOutputStream fos = null;
 	private BufferedOutputStream bos = null;
 	private PrintWriter out = null;
 	
 	private StringBuffer head = new StringBuffer();
 	private int total = 0;
 	private byte[] fileData;
 	private int pl;
 	private boolean single = true;					//标示编码的文件是否为单文件
 	private String root = null, outFile = null;
 	
 	public EncoderBencoding(){

		this.setPL(this.PIECE_LENGTH256);
		this.setSingle(false);
		
/*要作一个自动分块的方法
 *
 *
 *
 *
 *
 *
 */
 	}
 	/**用来打开输入文件
 	 */
 	private boolean openInFile() throws IOException{
 		//现实文件选择框
 		JFileChooser jfc = new JFileChooser();
 		int state = jfc.showOpenDialog(null);

	 	if (state == JFileChooser.APPROVE_OPTION ) inFileName = jfc.getSelectedFile();
	 	else return false;
 		
 		total = (int)inFileName.length();
 		fileData = new byte[total];
 		
 		fis = new FileInputStream(inFileName);
 		in = new BufferedInputStream(fis);
 		
 		return true;
 	}
 	 /**用来打开输出文件
 	 */
 	private void openOutFile() throws IOException{
 		String tempFile = "riverfile\\" + inFileName.getName() + ".river";
 		outFileName = new File(tempFile);

 		fos = new FileOutputStream(outFileName);
 		bos = new BufferedOutputStream(fos);
 		out = new PrintWriter(fos);
 	}
 	
 	//返回每个键名的字符串长度
 	private String keyCount(String keyName){
 		String result = new Integer(keyName.getBytes().length).toString();
 		result += ":";
 		return result;
 	}
 	
 	//返回整数的字符串
 	private String getIntString(int keyValue){
 		return  new Integer(keyValue).toString();
 	}
 	
 	//返回当前时间,Unix标准时间,
 	//从1970年1月1日 00:00:00 到目前的描秒数
 	private String getCurrentTime(){
 		Date date = new Date();
 		long time = date.getTime();
 		time /= 1000;
 		String result = new Long(time).toString();
 		return result;
 	}
 	
 	//计算单文件的sha1 hash
 	private void parseSHA1_single() throws IOException{
		Status status = new Status(total);
 		
 		MessageDigest sha = null;
 		byte[] hash = new byte[20];
 		fileData = new byte[pl];
 		int kuai = (total%pl == 0)?total/pl:(total/pl+1);
		
 		out.print((new Integer(kuai*20).toString()) + ":");
 		out.flush();
 		
		try{
			sha = MessageDigest.getInstance("sha-1");
		}catch (NoSuchAlgorithmException e) {System.out.println("Error! 无效编码NoSuchAlgorithm!");return;}
		
		for (int i=0;i<kuai;i++){
			
			in.read(fileData);
			sha.update(fileData);
			hash = sha.digest();
			
			bos.write(hash);
			status.setValue((i+1)*pl);
		}
		status.dispose();
		bos.flush();
		out.write("ee");
		out.flush();
		out.close();
		bos.close();
		fos.close();
		in.close();
		fis.close();
 	}
 	//计算多文件的sha1 hash
 	private void parseSHA1_multiple()  throws IOException{
		long kuai = 0;
		String subPath = null,path = null,temp = null;
 		MessageDigest sha = null;
 		byte[] hash = new byte[20];
 		Vector files = foundFiles();
		if (files == null ) {
			System.out.println("取消了选择文件的操作。");
			return;
		}
 		File f =null;
 		int[] kuais = new int[files.size()];
 		
 		out.print(head.toString());
 		out.flush();

		pathAddToFile(files);
 		
 		out.print("e4:name");
 		out.print(keyCount(outFile) + outFile);
		out.print(keyCount(piece_length) + piece_length);
		out.print("i" + getIntString(pl) + "e");
 		out.print("6:pieces");
		
		for(int i=0;i<files.size();i++){
			subPath = (String)files.get(i);
 			path = root + subPath;
 			f = new File(path);
 			
 			total = (int)f.length();
 			kuais[i] = (total%pl == 0)?total/pl:(total/pl+1);
 			kuai += kuais[i];
 		}
 		out.print((new Long(kuai*20).toString()) + ":");
 		out.flush();
 		
 		System.out.println("开始对文件夹中的每个文件编码...");
 		Status status = new Status(kuais[0]);
 		fileData = new byte[pl];
 		try{
			sha = MessageDigest.getInstance("sha-1");
		}catch (NoSuchAlgorithmException e) {System.out.println("Error! 无效编码NoSuchAlgorithm!");return;}
 		for(int j=0;j<files.size();j++){
			inFileName = new File(root + (String)files.get(j));
 			fis = new FileInputStream(inFileName);
 			in = new BufferedInputStream(fis);
 			
 			status.setMax(kuais[j]);
			for (int i=0;i<kuais[j];i++){
				
				in.read(fileData);
				sha.update(fileData);
				hash = sha.digest();
				
				bos.write(hash);
				bos.flush();
				status.setValue(i+1);
			}
 		}
 		status.dispose();
		out.write("e");
		out.flush();
		out.close();
		bos.close();
		fos.close();
		in.close();
		fis.close();
 	}
 	
 	//此方法用于将补充元信息文件
 	private void pathAddToFile(Vector s){
 		File f = null;
 		String subPath = null,path = null,temp = null;
 		
		for(int i=0;i<s.size();i++){
			subPath = (String)s.get(i);
 			path = root + subPath;
 			f = new File(path);
 			
 			out.print("d6:" + "length");
 			out.print("i" + getIntString((int)f.length()) + "e");
 			out.print("4:" + "pathl");
 			StringTokenizer st = new StringTokenizer(subPath,"\\");
 			while (st.hasMoreTokens()) {
 				temp = st.nextToken();
 				out.print(keyCount(temp) + temp);
 			}
 			out.print("ee");
 			out.flush();
 		}
 	}
 	//用于查找指定目录中的文件
 	private Vector foundFiles() throws IOException{
 		File[] temp = null;
 		Vector files = new Vector(5);
 		Stack directoreis = new Stack();
 		File current;
 		int String_index = 0;
 		
 		JFileChooser jfc = new JFileChooser();
		jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		
		//选择要发布的文件夹
		int state = 0 ,response = 10;
		while (response != 0){
			state = jfc.showDialog(null,"Select");
			inFileName = jfc.getSelectedFile();
			
			if ( state != JFileChooser.APPROVE_OPTION ) return null;
			
	 		response = JOptionPane.showConfirmDialog(null,"是否选择:\""+inFileName.getPath()+"\"目录?",
	 													"确认!",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
		}
		
		//处理选择的文件夹
		root = inFileName.getPath();
		outFile = inFileName.getName();
		String_index = root.length();
		
		System.out.println("正在分析文件夹...");
		current = new File(root);
 		temp = current.listFiles();
		while ( true ){
			for (int i=0;i<temp.length;i++){
				if (temp[i].isDirectory()) directoreis.push(temp[i]);
				else {
					files.addElement(temp[i].getAbsolutePath().substring(String_index));
				}
			}
			if (directoreis.empty()) break;
			temp = ((File)directoreis.pop()).listFiles();
		}
		
 		String tempFile = "riverfile\\" + outFile + ".river";
 		outFileName = new File(tempFile);

 		fos = new FileOutputStream(outFileName);
 		bos = new BufferedOutputStream(fos);
 		out = new PrintWriter(fos);
 		
 		return files;
 	}
 	public void setPL(int i){
 		this.pl = i;
 	}
 	public void setSingle(boolean b){
 		this.single = b;
 	}
 	/**具体的编码工作
 	 *不返回任何数据
 	 */
 	public void encoderBencoding(){
 		head.append("d");
 		head.append(keyCount(creation_date) + creation_date);
 		head.append("i" + getCurrentTime() + "e");
 		
 		head.append(keyCount(created_by) + created_by);
 		head.append(keyCount("Sinpool") + "Sinpool");
 		
 		new File("riverfile").mkdir();		//创建保存元文件的文件夹,以免用户误删除。
 		
 		//如果是单文件
 		if ( single ) {
 			head.append(keyCount(type) + type);
 			head.append(keyCount("single") + "single");
 			
 			try{
 				if ( openInFile() ) openOutFile();
 				else {
 					System.out.println("没有选择要发布的文件,放弃了操作!");
 					return;
 				}
 			}catch (IOException ioe) {
 				 	System.out.println("选择要发布的文件时出错!");
 					return;
 			}
 			head.append(keyCount(info) + info + "d");
 			
 			head.append(keyCount(length) + length);
 			head.append("i" + getIntString(total) + "e");
 			
 			head.append(keyCount(name) + name);
 			head.append(keyCount(inFileName.getName()) + inFileName.getName());
 			
 			head.append(keyCount(piece_length) + piece_length);
 			head.append("i" + getIntString(pl) +"e");
 			
 			head.append(keyCount(pieces) + pieces);

 			out.print(head.toString());
 			out.flush();
 			
 			try{
 				this.parseSHA1_single();
 			}catch (IOException e) {System.out.println("转换sha1 hash时出错!");return;}
 		}
 		//如果是多文件
 		else {
 			head.append(keyCount(type) + type);
 			head.append(keyCount("multiple") + "multiple");
 			
 			head.append(keyCount(info) + info + "d");
 			head.append(keyCount(files) + files + "l");
				
 			try{
 				this.parseSHA1_multiple();
 			}catch (IOException e) {System.out.println("转换sha1 hash时出错!");return;}
 		}
 	}
 	
 	//获得元文件文件名
 	public String getRiverscentFileName(){
 		return outFileName.getName();
 	}
	//获得共享文件绝对路径名,单文件时使用。
	public String getShareFileAbsoluteFileName(){
		return inFileName.getAbsolutePath();
	}
	//获得共享文件的路径,多文件时使用。
	public String getShareFilePath(){
		return root;
	}
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -