JAvaは大きなファイルのブレークポイント転送をサポートするSocket


ここでは、スレッドプールを使用してSocketサービスを作成し、大きなファイルのブレークポイントの継続をサポートする方法について説明します.
まず、ツールクラスを作成します.
package com.android.server.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;

public class StreamTool {

	/**
	 *     
	 * 
	 * @param file
	 *                
	 * @param data
	 *                 
	 * @throws Exception
	 */
	public static void save(File file, byte[] data) throws Exception {
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		fileOutputStream.write(data);
		fileOutputStream.close();
	}

	/**
	 *     
	 * @param in     
	 * @return    
	 * @throws IOException
	 */
	public static String readLine(PushbackInputStream in) throws IOException {
		char[] buf = new char[128];
		int room = buf.length;
		int offset = 0;
		int c;
		loop: while (true) {
			switch (c = in.read()) {
			case -1:
			case '
': break loop; case '\r': int c2 = in.read(); if (c2 != '
' && c2 != -1) in.unread(c2); break loop; default: if (--room < 0) { char[] lineBuffer = buf; buf = new char[offset + 128]; room = buf.length - offset - 1; System.arraycopy(lineBuffer, 0, buf, 0, offset); } buf[offset++] = (char) c; break; } } if (c == -1 && offset == 0) return null; return String.copyValueOf(buf,0,offset); } /** * * @param inStream * @return * @throws Exception */ public static byte[] readStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outputStream=new ByteArrayOutputStream(); byte [] buf=new byte[1024]; int len=-1; while((len=inStream.read(buf))!=1){ outputStream.write(buf,0,len); } outputStream.close(); inStream.close(); return outputStream.toByteArray(); } }

このツールクラスは主にファイルの読み書きを実現します.
このSocketの書き方を見てみましょう
コードを参照:
package com.android.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.io.RandomAccessFile;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.android.server.util.StreamTool;

public class SocketServer {
	private ExecutorService executorService;//    
	private ServerSocket server = null;
	private int port;//   
	private boolean quit;//       
	private Map<Long, FileLog> datas = new HashMap<Long, FileLog>();//       

	public SocketServer(int port) {
		this.port = port;
		//       
		executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
				.availableProcessors() * 50);//   cpu ,cpu         

	}

	public void start() throws IOException {
		server = new ServerSocket(port);
		while (!quit) {
			Socket socket = server.accept();//         
			executorService.execute(new SocketTask(socket));//           
			
		}
	}
	
	public void quit(){
		this.quit=true;
		try {
			server.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private class SocketTask implements Runnable {

		private Socket socket;

		public SocketTask(Socket socket) {
			this.socket = socket;
		}

		@Override
		public void run() {
			try {
				System.out.println("accepted connection from"
						+ socket.getInetAddress() + "@" + socket.getPort());

				PushbackInputStream inputStream = new PushbackInputStream(
						socket.getInputStream());

				//              :Content-Length=143253434;filename=xxx.3gp;sourceid=
				//        sourceid  
				String head = StreamTool.readLine(inputStream);
				System.out.println(head);

				if (head != null) {
					String[] items = head.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);
					long id = System.currentTimeMillis();//   id
					FileLog log = null;
					if (null != sourceId && !"".equals(sourceId)) {
						id = Long.valueOf(sourceId);
						log = find(id);//             
					}

					File file = null;//      
					int position = 0;//     

					//               ,         
					if (log == null) {
						String path = new SimpleDateFormat(
								"yyyy/MM/dd/HH/mm/ss").format(new Date());
						File dir = new File("file/" + path);
						if (!dir.exists())
							dir.mkdirs();

						file = new File(dir, fileName);//       
						if (file.exists()) {//          
							fileName = fileName.substring(0,
									fileName.indexOf("."))
									+ dir.listFiles().length
									+ fileName.substring(fileName.indexOf("."));
							file = new File(dir, fileName);
						}
						save(id, file);
					} else {//         ,       
						file = new File(log.getPath());
						if (file.exists()) {
							File logFile = new File(file.getParentFile(),
									file.getName() + ".log");
							if (logFile.exists()) {
								Properties properties = new Properties();
								properties.load(new FileInputStream(logFile));
								position = Integer.valueOf(properties
										.getProperty("length"));//        
							}

						}

					}
					//             ,          :sourceid, position    
					OutputStream outputStream = socket.getOutputStream();
					String respons = "sourceid=" + id + "position" + position
							+ "\r
"; outputStream.write(respons.getBytes()); RandomAccessFile accessFile = new RandomAccessFile(file, "rwd"); if(position==0) accessFile.setLength(Integer.valueOf(fileLength));// accessFile.seek(position);// byte [] buf=new byte[1024]; int len=1; int length=position; while((len=inputStream.read(buf))!=-1){ accessFile.write(buf,0,len); length+=len; Properties properties=new Properties(); properties.put("length", String.valueOf(length)); FileOutputStream fileOutputStream=new FileOutputStream(new File(file.getParent(),file.getName()+".log")); properties.store(fileOutputStream, null);// fileOutputStream.close(); } if(length==accessFile.length()) delete(id); accessFile.close(); inputStream.close(); outputStream.close(); } } catch (Exception e) { }finally{ if(socket!=null&&!socket.isClosed()) try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public static void main(String[] args) { String s = "12345"; System.out.println(s.indexOf("5")); System.out.println(s.substring(2, s.indexOf("5"))); } /** * * * @param sourceId * Id * @return */ public FileLog find(long sourceId) { return datas.get(sourceId); } /** * * * @param id * id * @param file * */ public void save(long id, File file) { datas.put(id, new FileLog(id, file.getAbsolutePath())); } /** * * * @param sourceId * Id */ public void delete(long sourceId) { if (datas.containsKey(sourceId)) { datas.remove(sourceId); } } private class FileLog { private long id; private String path; public FileLog(long id, String path) { this.id = id; this.path = path; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } } }

次のアップロードを容易にするために、ファイルのブレークポイント位置を格納するためにMapオブジェクトを使用しました.ExecutorServiceスレッドプールは、SocketTaskのスレッドを管理するために使用されます.FileLogは私たちのファイルごとに実際に保存されているクラスです!
これで簡単なブレークポイントアップロードサービスを完了しました.