code: package resa.migrate;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.DataInputStream;
  import java.io.DataOutputStream;
  import java.io.IOException;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.nio.file.StandardCopyOption;
  
  /**
   * Created by ding on 14-7-31.
   */
  public class FileServer extends Thread {
  
      private static final Logger LOG = LoggerFactory.getLogger(FileServer.class);
  
      private final int port;
      private ServerSocket serverSocket;
      private final Path root;
      private volatile boolean stop = false;
  
      public FileServer(int port, String base) {
          super("File server");
          setDaemon(true);
          root = Paths.get(base);
          this.port = port;
      }
  
      public void run() {
          try {
              serverSocket = new ServerSocket(port);
              System.out.println("Server started at port " + port);
          } catch (Exception e) {
              System.err.println("Port " + port + " already in use.");
              return;
          }
          while (!stop) {
              try {
                  Socket clientSocket = serverSocket.accept();
                  // System.out.println("Accepted connection : " + clientSocket);
                  Thread t = new Thread(new Connection(clientSocket));
                  t.start();
              } catch (Exception e) {
                  System.err.println("Error in connection attempt.");
              }
          }
      }
  
      public static void main(String[] args) throws InterruptedException {
          FileServer server = new FileServer(Integer.parseInt(args[0]), args[1]);
          server.start();
          server.join();
      }
  
      private class Connection implements Runnable {
          private Socket clientSocket;
  
          public Connection(Socket client) {
              this.clientSocket = client;
          }
  
          @Override
          public void run() {
              try (DataInputStream in = new DataInputStream(clientSocket.getInputStream())) {
                  String clientSelection = in.readUTF();
                  switch (clientSelection) {
                      case "write":
                          receiveFile(in, in.readUTF());
                          break;
                      case "read":
                          String outGoingFileName = in.readUTF();
                          sendFile(outGoingFileName);
                          break;
                      default:
                          System.out.println("Incorrect command received.");
                          break;
                  }
              } catch (IOException ex) {
                  ex.printStackTrace();
              } finally {
                  try {
                      clientSocket.close();
                  } catch (IOException e) {
                  }
              }
          }
  
          public void receiveFile(DataInputStream clientData, String fileName) {
              Path destFile = root.resolve(fileName);
              try {
                  Path tmpFile = Files.createTempFile("recv-tmp-", ".tmp");
                  Files.copy(clientData, tmpFile, StandardCopyOption.REPLACE_EXISTING);
                  Files.move(tmpFile, destFile, StandardCopyOption.REPLACE_EXISTING);
                  LOG.debug("File {} received from client", fileName);
              } catch (IOException ex) {
                  LOG.info("Recv file failed, name=" + fileName, ex);
              }
          }
  
          public void sendFile(String file) {
              try (DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream())) {
                  //handle file read
                  Path myFile = root.resolve(file);
                  if (Files.exists(myFile)) {
                      out.writeLong(Files.size(myFile));
                      Files.copy(myFile, out);
                  } else {
                      out.writeLong(-1L);
                  }
              } catch (IOException e) {
                  LOG.info("send file failed, name=" + file, e);
              }
          }
      }
  }
  