package thread;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.util.Map;
import java.util.Properties;
import model.FileLog;
/**
* 上传线程
*
* @author 赵庆洋
*
*/
public class UpThread extends Thread {
private Socket socket;
private Map<Long, FileLog> datas;
public final static int BUFFER = 1024;
public UpThread(Socket socket, Map<Long, FileLog> datas) {
this.socket = socket;
this.datas = datas;
}
/**
* 上传方法
*/
public void upLoad() {
try {
System.out.println("开始上传");
DataInputStream inStream = new DataInputStream(
socket.getInputStream());
// 获取从客户端传来的参数
String params = inStream.readUTF();
System.out.println("params: " + params);
if (params != null) {
// 下面从协议数据中读取各种参数值
String[] items = params.split(";");
// 要上传文件的长度
String filelength = items[0]
.substring(items[0].indexOf("=") + 1);
// 文件名称(带后缀名)
String filename = items[1].substring(items[1].indexOf("=") + 1);
// 上传过的记录的唯一标示符
String sourceid = items[2].substring(items[2].indexOf("=") + 1);
// 要上传到电脑的目录路径
String filepath = items[3].substring(items[3].indexOf("=") + 1);
// 临时文件名称
String tempname = filename.substring(0, filename.indexOf("."))
+ ".tmp";
// 每个上传记录的唯一标示符
Long id = System.currentTimeMillis();
// 下载的记录
FileLog log = null;
// 如果手机端有存储上传记录的标示符
if (null != sourceid && !"".equals(sourceid)) {
id = Long.valueOf(sourceid);
// 查找上传的文件是否存在上传记录
log = find(id);
}
// 下载的文件
File file = null;
// 临时的文件
File tempfile = null;
long position = 0;
// 如果不存在上传记录 为文件添加记录
if (log == null) {
// 目录
File dir = new File(filepath);
if (!dir.exists()) {
dir.mkdirs();
}
// 文件
file = new File(dir, filename);
tempfile = new File(dir, tempname);
// 如果文件存在 改名
if (file.exists()) {
filename = filename.substring(0,
filename.indexOf(".") - 1)
+ dir.listFiles().length
+ filename.substring(filename.indexOf("."));
tempname = filename.substring(0, filename.indexOf("."))
+ ".tmp";
file = new File(dir, filename);
tempfile = new File(dir, tempname);
}
save(id, file, tempfile);
}
// 如果存在记录,读取上次的断点
else {
file = new File(log.getPath());
tempfile = new File(log.getTempPath());
if (tempfile.exists()) {
File logFile = new File(file.getParentFile(),
file.getName() + ".log");
if (logFile.exists()) {
Properties properties = new Properties();
properties.load(new FileInputStream(logFile));
// 读取断点的位置
position = Long.valueOf(properties
.getProperty("length"));
System.out.println("position: " + position);
}
}
}
// 向客户端发送sourceid和断点position
DataOutputStream dataOutputStream = new DataOutputStream(
socket.getOutputStream());
String response = "sourceid=" + id + ";position=" + position;
System.out.println("position: " + position);
// sourceid由服务生成,唯一标识上传的文件,position指示客户端从文件的什么位置开始上传
dataOutputStream.writeUTF(response);
dataOutputStream.flush();
inStream = new DataInputStream(socket.getInputStream());
// 向硬盘写文件
RandomAccessFile fileOutStream = new RandomAccessFile(tempfile,
"rwd");
if (position == 0) {
fileOutStream.setLength(Long.valueOf(filelength));
}
// 移动到文件指定位置开始写数据
fileOutStream.seek(position);
byte[] buffer = new byte[BUFFER];
int len = -1;
long length = position;
while ((len = inStream.read(buffer)) != -1) {
fileOutStream.write(buffer, 0, len);
length += len;
Properties properties = new Properties();
properties.put("length", String.valueOf(length));
FileOutputStream logFile = new FileOutputStream(new File(
file.getParentFile(), file.getName() + ".log"));
// 实时记录文件的最后保存位置
properties.store(logFile, null);
logFile.close();
}
if (length == Long.valueOf(filelength)) {
fileOutStream.close();
if (tempfile.renameTo(file)) {
File logFile = new File(file.getParentFile(),
file.getName() + ".log");
if (logFile.exists()) {
logFile.delete();
}
delete(id);
System.out.println("上传成功");
}
} else {
System.out.println("上传中断");
fileOutStream.close();
}
inStream.close();
dataOutputStream.close();
file = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public FileLog find(Long sourceid) {
return datas.get(sourceid);
}
// 当文件上传完毕,删除记录
public void delete(long sourceid) {
if (datas.containsKey(sourceid))
datas.remove(sourceid);
}
// 保存上传记录
public void save(Long id, File saveFile, File tempFile) {
// 日后可以改成通过数据库存放
FileLog fileLog = new FileLog();
fileLog.setId(id);
fileLog.setPath(saveFile.getAbsolutePath());
fileLog.setTempPath(tempFile.getAbsolutePath());
datas.put(id, fileLog);
}
@Override
public void run() {
upLoad();
super.run();
}
}