package zutil.net; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.ArrayList; import zutil.ProgressListener; import zutil.io.MultiPrintStream; import zutil.io.file.FileUtil; /** * This class connects to a update server and updates a path * with the servers * * @author Ziver * */ public class UpdateClient{ private ArrayList clientFileList; private Socket socket; private String path; private ProgressListener progress; private int speed; private long totalReceived; /** * Creates a UpdateClient * * @param address Address to the UpdateServer * @param port The port on the server * @param path Path to the files to update * @throws Exception */ public UpdateClient(String address, int port, String path) throws Exception{ clientFileList = UpdateServer.getFileList(path); socket = new Socket(address, port); this.path = path; } public void setProgressListener(ProgressListener p){ progress = p; } /** * Updates the files * * @throws Exception */ public void update() throws Exception{ ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); // send client file list out.writeObject(clientFileList); out.flush(); // receive file updates FileHash fileInfo = (FileHash)in.readObject(); File tmpPath = FileUtil.find(path); while(!fileInfo.path.isEmpty()){ MultiPrintStream.out.println("Updating: "+path+fileInfo.path); // reading new file data File file = new File(tmpPath.getAbsolutePath()+fileInfo.path); File tmpFile = File.createTempFile(file.getName(), ".tmp", tmpPath); tmpFile.getParentFile().mkdirs(); tmpFile.deleteOnExit(); FileOutputStream fileOut = new FileOutputStream(tmpFile); byte[] buffer = new byte[socket.getReceiveBufferSize()]; int bytesReceived = 0; totalReceived = 0; long time = System.currentTimeMillis(); long timeTotalRecived = 0; while((bytesReceived = in.read(buffer)) > 0) { fileOut.write(buffer, 0, bytesReceived); if(time+1000 < System.currentTimeMillis()){ time = System.currentTimeMillis(); speed = (int)(totalReceived - timeTotalRecived); timeTotalRecived = totalReceived; } totalReceived += bytesReceived; if(progress != null) progress.progressUpdate(this, fileInfo, (double)totalReceived/fileInfo.size*100); } fileOut.close(); speed = 0; // delete old file and replace whit new file.delete(); if(!tmpFile.renameTo(file)){ throw new Exception("Cannot update file: "+file.getAbsolutePath()); } // read new message fileInfo = (FileHash)in.readObject(); } MultiPrintStream.out.println("Update Done!!"); } /** * Returns the speed of the transfer * * @return The speed in bytes/s */ public int speed(){ return speed; } /** * Returns the total amount of data received for the * current file * * @return The speed in bytes/s */ public long totalReceived(){ return totalReceived; } /** * Closes the connection * * @throws IOException */ public void close() throws IOException{ socket.close(); } }