断点续传原理:(以后慢慢来改进)
http://www.apkbus.com/android-18964-1-1.html
server端
package com.wodexiangce.util.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.math.BigDecimal;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.wodexiangce.util.Constant;
public class FileServer extends Thread{
private static final long serialVersionUID = 1L;
private ExecutorService executorService;//线程池
private int port = 8999;//监听端口
private ServerSocket server;
public FileServer(int port)
{
this.port = port;
// //创建线程池,池中具有(cpu个数*50)条线程
executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 50);
}
/**
* 启动服务
* @throws Exception
*/
public void run() {
try {
server = new ServerSocket(port);//实现端口监听
} catch (IOException e1) {
e1.printStackTrace();
}
while(true){
try{
Socket socket = server.accept();
executorService.execute(new SocketTask(socket));//为支持多用户并发访问,采用线程池管理每一个用户的连接请求
}catch (Exception e){
e.printStackTrace();
}
}
}
private class SocketTask implements Runnable{
private Socket socket = null;
public SocketTask(Socket socket){
this.socket = socket;
}
public void run(){
InputStream inStream = null;
OutputStream outStream = null;
RandomAccessFile fileOutStream=null;
boolean isTrue = false;
/***
* 构造路径
*/
String logFolder="";
String imageFolder ="";
String imageSuffix_temp = "";
String imageSuffix ="";
String logSuffix = "";
String logFile = "";
String imageFile_temp = "";
String imageFile = "";
try{
System.out.println("FileServer accepted connection "+ socket.getInetAddress()+ ":"+ socket.getPort());
//得到客户端发来的第一行协议数据:Content-Length=143253434;filename=xxx.3gp;sourceid=
//如果用户初次上传文件,sourceid的值为空。
inStream = socket.getInputStream();
String logFileName = StreamTool.readLine(inStream);
System.out.println("FileServer head:"+logFileName);
if(logFileName!=null){
//下面从协议数据中提取各项参数值
String[] items = logFileName.split(";");
String filelength = items[0].substring(items[0].indexOf("=")+1);//图片大小
String imageName = items[1].substring(items[1].indexOf("=")+1);//图片名称
String sourceid = items[2].substring(items[2].indexOf("=")+1);//图片标识
String userId = items[3].substring(items[3].indexOf("=")+1);//用户id
/***
* 构造路径
*/
logFolder=Constant.PARENTLOGPATH+userId+"/";
imageFolder = Constant.PARENTIMAGEPATH+userId+"/";
imageSuffix_temp = imageName.substring(imageName.lastIndexOf("."))+".temp";
imageSuffix = imageName.substring(imageName.lastIndexOf("."));
logSuffix = ".log";
logFile = logFolder+sourceid+logSuffix;
imageFile_temp = imageFolder + sourceid + imageSuffix_temp;
imageFile = imageFolder + sourceid + imageSuffix;
long position = 0;
//日志文件夹
File dir = new File(logFolder);
if(!dir.exists()){
dir.mkdirs();
}
//图片文件夹
File dir1 = new File(imageFolder);
if(!dir1.exists()){
dir1.mkdirs();
}
dir = new File(logFile);
//如果上传的文件不存在上传记录,为文件添加跟踪记录
if(!dir.exists()){
/**
* 日志文件存放的位置
*/
File file = new File(logFile);//这里这个构造起来的文件不会有重名情况
file.createNewFile();
/**
* 图片文件的存放位置
*/
System.out.println(imageFile_temp);
File file1 = new File(imageFile_temp);//这里这个构造起来的文件不会有重名情况
file1.createNewFile();
}else{
// 如果上传的文件存在上传记录,读取上次的断点位置
System.out.println("FileServer have exits log not null");
logFile = logFolder + sourceid + logSuffix;
imageFile_temp = imageFolder + sourceid + imageSuffix_temp;
imageFile = imageFolder + sourceid + imageSuffix;
//从上传记录中得到文件的路径
File file = new File(logFile);
if(file.exists())
{
Properties properties = new Properties();
properties.load(new FileInputStream(file));
//读取断点位置
position = Long.valueOf(properties.getProperty("length"));
}
}
//***************************上面是对协议头的处理,下面正式接收数据***************************************
//向客户端请求传输数据
outStream = socket.getOutputStream();
String response = "sourceid="+ sourceid+ ";position="+ position;
System.out.println(response);
//服务器收到客户端的请求信息后,给客户端返回响应信息:sourceid=1274773833264;position=position
//sourceid由服务生成,唯一标识上传的文件,position指示客户端从文件的什么位置开始上传
PrintStream ps = new PrintStream(outStream);
ps.println(response);
fileOutStream = new RandomAccessFile(imageFile_temp, "rwd");
//设置文件长度
if(position==0) {
fileOutStream.setLength(Integer.valueOf(filelength));
}
//移动文件指定的位置开始写入数据
fileOutStream.seek(position);
byte[] buffer = new byte[1024];
int len = -1;
long length = position;
int i=0;
System.out.println("ssss=="+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 logfos = new FileOutputStream(new File(logFile));
//实时记录文件的最后保存位置
properties.store(logfos, null);
logfos.close();
i++;
}
System.out.println("发送次数为:"+ i);
//如果长传长度等于实际长度则表示长传成功
System.out.println(length+"><"+fileOutStream.length()+"><"+Integer.valueOf(filelength));
if(length>=fileOutStream.length()){
isTrue = true;
}
}
}catch (Exception e){
e.printStackTrace();
}finally{
try{
if(socket!=null && !socket.isClosed()) {
socket.close();
}
if(inStream!=null){
inStream.close();
}
if(outStream!=null){
outStream.close();
}
if(fileOutStream!=null){
fileOutStream.close();
}
} catch (IOException e){
e.printStackTrace();
}finally{
if(isTrue){//删除日志文件,修改文件名字
File file = new File(logFile);
boolean bd = file.delete();
System.out.println("db=="+bd);
File file_temp = new File(imageFile_temp);
file_temp.renameTo(new File(imageFile));
}
}
}
}
public void operationPhoto(String imageFile){
String imageFileNoSuffix = imageFile.substring(0,imageFile.lastIndexOf(".")-1);
String imageSuffix = imageFile.substring(imageFile.lastIndexOf("."));
List<AppPhoto> appPhotoList = new ArrayList<AppPhoto>();
AppPhoto appPhotoLittle = new AppPhoto();
appPhotoLittle.setCompressHeight(new BigDecimal(8000));
appPhotoLittle.setCompressWidth(new BigDecimal(8000));
appPhotoLittle.setHeight(new BigDecimal(800));
appPhotoLittle.setWidth(new BigDecimal(900));
appPhotoLittle.setFilePath(imageFile);
appPhotoLittle.setFilePath(imageFileNoSuffix+"_1"+imageSuffix);
appPhotoList.add(appPhotoLittle);
AppPhoto appPhotoMiddle = new AppPhoto();
appPhotoMiddle.setCompressHeight(new BigDecimal(8000));
appPhotoMiddle.setCompressWidth(new BigDecimal(8000));
appPhotoMiddle.setHeight(new BigDecimal(800));
appPhotoMiddle.setWidth(new BigDecimal(900));
appPhotoMiddle.setFilePath(imageFile);
appPhotoMiddle.setFilePath(imageFileNoSuffix+"_1"+imageSuffix);
appPhotoList.add(appPhotoMiddle);
AppImagesManager appImagesManager = new AppImagesManager(appPhotoList);
appImagesManager.operation();
}
}
public static void main(String[] args) {
try{
FileServer fs = new FileServer(8999);
fs.run();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
client端
package com.wodexiangce.util.file;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TalkServer {
private static String str = "";
/**
* @param args
*/
public static void main(String[] args) {
TalkServer ts = new TalkServer();
ts.execesff();
}
public void execesff() {
int numTasks = 7;
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < numTasks; i++) {
str = i + "QQ";
System.out.println(str);
try {
exec.execute(new createTask(i));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("===" + i + "==");
}
}
class createTask implements Runnable {
Socket socket;
PrintWriter os;
BufferedReader is;
int count = 0;
public createTask(int count) {
this.count = count;
}
public void run() {
try {
Socket socket = new Socket("192.168.0.192", 8999);
// 向8899端口发出客户请求
os = new PrintWriter(socket.getOutputStream());
// 由Socket对象得到输出流,并构造PrintWriter对象
is = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
String readline = "Content-Length=10673753;filename=2572038_001950024728_2.jpg;sourceid="+ UUID.randomUUID() + ";userId=11132";
/***
* 参数说明 Content-Length=12321
* 图片2572038_001950024728_2.jpg长度为12321个字节
* filename=2572038_001950024728_2.jpg 图片名称 sourceid=; 图片唯一标识码
* userId=11132;当前用户id
*/
os.println(readline);// 将从系统标准输入读入的字符串输出到Server
os.flush();// 刷新输出流,使Server马上收到该字符串
System.out.println("Client:" + readline);
String readLine = is.readLine();
System.out.println("Server:" + readLine);// Server返回参数
int position = Integer.parseInt(readLine.split(";")[1].substring(readLine.indexOf("=") + 1));
String filePath = "D:\\2572038_001950024728_2_" + count+ ".jpg";// 图片路径
File fi = new File(filePath);
System.out.println("文件长度:" + fi.length());
System.out.println("position=" + position);
RandomAccessFile fileOutStream = new RandomAccessFile(fi, "r");
// 设定到上次传输的位置
fileOutStream.seek(Integer.valueOf(position));
OutputStream outStream = socket.getOutputStream();
PrintStream ps = new PrintStream(outStream);
byte[] buffer = new byte[1024];
int len = -1;
int length = Integer.valueOf(position);// 用来记录目前上传情况
/***
* 开始第二次向server端发送数据(这次发送的是文件的字节流)
*/
while ((len = fileOutStream.read(buffer)) != -1) {
System.out.println("len=" + len);
ps.write(buffer, 0, len);
// 设置长传数据长度
length += len;
// System.out.println("length=" + length);
// if(length>3753){//测试断点
// break;
// }
}
} catch (Exception e) {
System.out.println("Error" + e);
// 出错,则打印出错信息
e.printStackTrace();
} finally {
if (os != null) {
os.close(); // 关闭Socket输出流
}
if (is != null) {
try {
is.close(); // 关闭Socket输入流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (socket != null && !socket.isClosed()) {// 关闭socket
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
1258

被折叠的 条评论
为什么被折叠?



