📄 filetransfer.java
字号:
package com.valhalla.jbother.jabber.smack;import javax.swing.*;import java.net.InetAddress;import java.net.ConnectException;import java.net.SocketException;import java.io.*;import java.nio.channels.*;import java.util.*;import java.nio.ByteBuffer;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/** * Created by luke on Feb 8, 2005 2:45:29 PM *//** * class for handling both sending and receiving files */public abstract class FileTransfer{ private static String fId = "$Id$"; protected StreamInitiation.FileDetails fileDetails; protected InetAddress inetAddress; protected int port; protected String sid; protected String jidFrom; protected String jidTo; protected ByteBuffer buffer; protected long fileSize = 0; protected ByteChannel byteChannel; protected FileChannel fileChannel; protected Vector listeners = new Vector(); protected boolean cancelled = false; public final static int BUFSIZE = 16384; /** * general purpose constructor for handling filetransfer actions (sending/receiving). * * @param aFileDetails - filedetails of file to send/receive * @param aHostname - hostname of source/destination * @param aPort - port to use for transfer * @param aSid - XMPP Stream ID for this transfer * @param aJidFrom - Initiator JID * @param aJidTo - Target JID */ public FileTransfer(StreamInitiation.FileDetails aFileDetails, String aHostname, int aPort, String aSid, String aJidFrom, String aJidTo) { fileDetails = aFileDetails; port = aPort; sid = aSid; jidTo = aJidTo; jidFrom = aJidFrom; fileSize = fileDetails.getFileSize(); buffer = ByteBuffer.allocateDirect(BUFSIZE); try { inetAddress = InetAddress.getByName(aHostname); byteChannel = getByteChannel(); fileChannel = getFileChannel(); } catch (FileNotFoundException e) { cleanUp(); } catch (ConnectException e) { cleanUp(); } catch (SocketException e) { cleanUp(); } catch (IOException e) { e.printStackTrace(); cleanUp(); } } public void cancelTransfer() { cancelled = true; } protected void notifyListeners( int progress, long currentPosition ) { for( int i = 0; i < listeners.size(); i++ ) { FileTransferProgressListener listener = (FileTransferProgressListener)listeners.get( i ); listener.progressUpdate( progress, currentPosition ); } } public void addProgressListener( FileTransferProgressListener listener ) { listeners.add( listener ); } public void removeProgressListener( FileTransferProgressListener listener ) { listeners.remove( listener ); } /** * write array of byte[] to the socket * @param bytesToWrite - array of byte to write * @return number of written bytes or -1 when error occurred */ protected int writeToSocket(byte[] bytesToWrite) { return writeToSocket(ByteBuffer.wrap(bytesToWrite)); } /** * write ByteBuffer to the socket * @param byteBuffer - ByteBuffer containing data to write * @return number of written bytes or -1 when error occurred */ protected int writeToSocket(ByteBuffer byteBuffer) { try { return byteChannel.write(byteBuffer); } catch (IOException e) { System.err.println("Cannot write to the socket!"); e.printStackTrace(); } return -1; } /** * read bytes from socket and put them in ByteBuffer buffer * @return number of read bytes, -1 in case of error */ protected int readFromSocket() { try { buffer.clear(); return byteChannel.read(buffer); } catch (IOException e) { System.err.println("Cannot write to the socket!"); e.printStackTrace(); } return -2; } /** * return a SHA1 hash of a given string * @param aString - string to convert * @return SHA1 hashsum */ protected String getSHA1HashString(String aString) { String out = new String(); try { byte[] digest; MessageDigest md = MessageDigest.getInstance("SHA1"); byte[] buf = new byte[aString.length()]; buf = aString.getBytes(); digest = md.digest(buf); // now convert it into a string String hexChar = null; if( digest != null) { for(int i=0;i<digest.length;i++) { if(digest[i] > 0) { hexChar = Integer.toHexString(digest[i]); } else if(digest[i] < 0) { hexChar = Integer.toHexString(digest[i]).substring(6); } else { hexChar = "00"; } // pad with 0 if it's needed out += (hexChar.length() < 2 ? "0" : "") + hexChar; } } return out; } catch (NoSuchAlgorithmException e) { System.err.println("SHA1 algorithm not supported!"); e.printStackTrace(); return null; } } /** * closes both channels */ public void cleanUp() { try { if(fileChannel != null) { fileChannel.close(); } if(byteChannel != null) { byteChannel.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * reads bytes from file channel and puts them into socket channel * @return true if success, false otherwise */ protected boolean transferFromFileToSocket() { return transferFromChannelToChannel(fileChannel,byteChannel); } /** * reads bytes from socket channel and puts them into data channel * @return true if success, false otherwise */ protected boolean transferFromSocketToFile() { return transferFromChannelToChannel(byteChannel, fileChannel); } /** * transfer data from one channel to another * @param aFromChannel - channel used for reading * @param aToChannel - channel used for writing * @return true if success, false otherwise */ private boolean transferFromChannelToChannel(ReadableByteChannel aFromChannel, WritableByteChannel aToChannel) { long current = 0; long loopCount = 0; long loopIncrement = fileSize / 50; Ticker ticker = new Ticker(current,fileSize); ticker.start(); buffer.clear(); try { while(aFromChannel.read(buffer) != -1 || buffer.position() > 0) { buffer.flip(); current += buffer.remaining(); ticker.setCurrentPosition(current); if( cancelled ) { aFromChannel.close(); aToChannel.close(); ticker.setDone(true); return false; } aToChannel.write(buffer); buffer.compact(); } } catch (ClosedChannelException e) { return false; } catch (IOException e) { e.printStackTrace(); return false; } notifyListeners( 100, current ); return true; } public boolean isByteChannelNull() { return ( byteChannel == null); } public StreamInitiation.FileDetails getFileDetails() { return fileDetails; } // abstract methods public abstract ByteChannel getByteChannel() throws IOException; public abstract FileChannel getFileChannel() throws FileNotFoundException; public abstract boolean authenticate(); /** * this thread wakes up every second and calls notifyListeners with current values * of "percent completed" and "number of bytes transferred" */ private class Ticker extends Thread { private long currentPosition; private long fileSize; private boolean done = false; public Ticker(long aCurrentPosition, long aFileSize) { super(); currentPosition = aCurrentPosition; fileSize = aFileSize; } public long getCurrentPosition() { return currentPosition; } public void setCurrentPosition(long aCurrentPosition) { currentPosition = aCurrentPosition; } public void setDone(boolean aDone) { done = aDone; } // wake up every second and update file progress dialog public void run() { int percent; try { while(! done) { Thread.sleep(500); percent = (int)(( (float)currentPosition / (float)fileSize ) * (float)100); notifyListeners( percent, currentPosition ); if(currentPosition == fileSize) { done = true; } } } catch(InterruptedException e) {} } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -