一、发送方代码:
import java.awt.*;
import java.awt.datatransfer.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Base64;
public class SendData {
/**
* 数据发送间隔时间,单位:毫秒,默认:1000毫秒,
* 取决于 1.需要等待剪切板被读取,2.间隔在500毫秒以下,可能会被系统禁止读写
*/
private int delay=2000;//发送延迟
private int once=600000;//每次发送的数据量 默认:60万字节,取决于双方网络带宽,以及系统剪切板容量
private int downtime=10;//准备倒计时,单位:秒,默认:10秒
private String filename;//发送的文件名
private Clipboard cb ;//剪切板
/**
* @param filename 文件名
*/
public SendData(String filename){
this.filename=filename;
}
public void start() throws IOException {
/**
* 开始倒计时
*/
System.out.println("倒计时"+downtime+"秒开始");
while (downtime> 0) {
System.out.println((downtime--)+"秒");
delay(1000);
}
/**
* 初始化编码器,文件,和文件流
*/
Base64.Encoder en = Base64.getEncoder();
cb=Toolkit.getDefaultToolkit().getSystemClipboard();
File file=new File(filename);
FileInputStream fi = new FileInputStream(file);
/**
* 发送文件名
*/
int sign = 1;//数据包标记
setClipboardText(sign + "@" +file.getName());
/**
* 开始发送数据
*/
long file_len=file.length();
long count = 0;//记录已发送长度
byte[] bytes = new byte[once];
int len=0;
while ((len=fi.read(bytes))>0){
/**
* 发送延迟
*/
delay(delay);
/**
* 将读到的字节转换为编码
*/
String temp_str="";
sign++;
count+=len;
if(len==once){
/*****************数据长度=字节数组最大容量,表示还没传送结束*********************/
temp_str=en.encodeToString(bytes);
System.out.println(sign+":已发送"+(count*100/file_len)+"%");
}else{
/*********************数据未填满字节数组,表示传送结束**************************/
byte[] temp_bytes=new byte[len];
System.arraycopy(bytes,0,temp_bytes,0,len);
temp_str=en.encodeToString(temp_bytes);
System.out.println(sign+":已发送100%");
}
/**
* 写入剪切板
*/
System.out.println("长度="+temp_str.length());
setClipboardText(sign + "@" +temp_str);
}
delay(delay);
setClipboardText("-1@");//发送结束标记
fi.close();
System.out.println("发送完成");
delay(delay);
setClipboardText("");
System.out.println("已清空剪切板内容");
}
public void setClipboardText(String text){
Transferable tf = new StringSelection(text);
cb.setContents(tf, null);
}
public void delay(int time){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public int getOnce() {
return once;
}
public SendData setOnce(int once) {
this.once = once;
return this;
}
public int getDowntime() {
return downtime;
}
public SendData setDowntime(int downtime) {
this.downtime = downtime;
return this;
}
public int getDelay() {
return delay;
}
public SendData setDelay(int delay) {
this.delay = delay;
return this;
}
public String getFilename() {
return filename;
}
public SendData setFilename(String filename) {
this.filename = filename;
return this;
}
}
二、接收方:
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.*;
import java.util.Base64;
public class ReceiveData {
private String dir_out="D:/dir_out/"; //默认输出路径
private String file_target; //保存文件名,默认使用接收来的文件名
private int read_time=1000; //读取延迟
private int time_out=15000; //最大等待时间(超时时间)
private Clipboard cb ;//剪切板
public ReceiveData(){}
/**
*
* @param file_target 自定义接收的文件名
*/
public ReceiveData(String file_target){
this.file_target=file_target;
}
/**
*
* @param dir_out 自定义接收路径
* @param file_target 自定义接收的文件名
*/
public ReceiveData(String dir_out,String file_target){
this.dir_out=dir_out;
this.file_target=file_target;
}
public void start() throws IOException, UnsupportedFlavorException {
/**
* 初始化操作
*/
int sign=0; //数据标记
float count_time=0;//累计等待时间
Base64.Decoder decoder=Base64.getDecoder();
cb= Toolkit.getDefaultToolkit().getSystemClipboard();
/**
* 创建输出路径及文件
*/
createDir(dir_out);
while (sign<1){
delay(read_time);
String text=getClipboardText();
int temp_sign=0;
int p=text.indexOf("@");
try {
temp_sign=Integer.parseInt(text.substring(0,p));
}catch (Exception e){
/**
* 利用String转int的异常,实现等待超时
*/
count_time+=read_time;
System.out.println("已等待"+(count_time/1000)+"秒");
if(count_time>=time_out&&sign==0){
System.out.println("超时退出");
System.exit(0);
}
continue;
}
/**
* 设置文件名
*/
sign=temp_sign;
if(file_target.equals("")){
setFile_target(text.substring(p+1));
}
}
/**
* 创建文件
*/
File target=new File(dir_out+file_target);
if(target.exists())target.delete();
target.createNewFile();
System.out.println("创建输出路径及文件");
/**
* 初始化剪切板,解码器,写入流等参数
*/
BufferedOutputStream bo=new BufferedOutputStream(new FileOutputStream(target));
/**
* 开始接收数据
*/
while (true){
delay(read_time);
String text=getClipboardText();
int temp_sign=0;
int p=text.indexOf("@");
temp_sign=Integer.parseInt(text.substring(0,p));
if(temp_sign<0)break;//结束
else if(sign==temp_sign)continue;//重复
else sign=temp_sign;//数据更新
System.out.println("数据包:"+sign);
bo.write(decoder.decode(text.substring(p+1)));
bo.flush();
}
bo.flush();
bo.close();
System.out.println("接收的文件大小"+target.length());
target=null;
}
/**
* 获取剪切板数据
* @return
* @throws IOException
* @throws UnsupportedFlavorException
*/
public String getClipboardText() throws IOException, UnsupportedFlavorException {
Transferable context=cb.getContents(null);
if(context!=null&&context.isDataFlavorSupported(DataFlavor.stringFlavor)){
return (String)context.getTransferData(DataFlavor.stringFlavor);
}
return "";
}
/**
*
* @param time 程序等待时间
*/
public void delay(int time){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 创建文件夹
* @param dir_path 文件夹路径
* @throws IOException
*/
public void createDir(String dir_path) throws IOException {
File dir=new File(dir_path);
if(!dir.exists()) dir.mkdirs();
}
public String getFile_target() {
return file_target;
}
public void setFile_target(String file_target) {
this.file_target = file_target;
}
public int getRead_time() {
return read_time;
}
public void setRead_time(int read_time) {
this.read_time = read_time;
}
public int getTime_out() {
return time_out;
}
public void setTime_out(int time_out) {
this.time_out = time_out;
}
}
三、测试:
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
new SendData("D:/456.zip" ).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
new ReceiveData().start();
} catch (IOException e) {
e.printStackTrace();
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
}
}
}).start();
}