0

我正在研究一个将文件从客户端传输到服务器的Java项目。现在我需要显示每个文件传输的进度条,即进度条应在每次传输开始时自动弹出。我已经制作了创建进度条的程序,但我无法将它与客户端-服务器程序合并。如果有人帮助我使用循环,我将不胜感激。谢谢你。

ClientMain.java

public class ClientMain {
private DirectoryTxr transmitter = null;
Socket clientSocket = null;
private boolean connectedStatus = false;
private String ipAddress;
String srcPath = null;
String dstPath = "";
public ClientMain() {

}

public void setIpAddress(String ip) {
    this.ipAddress = ip;
}

public void setSrcPath(String path) {
    this.srcPath = path;
}

public void setDstPath(String path) {
    this.dstPath = path;
}

private void createConnection() {
    Runnable connectRunnable = new Runnable() {
        public void run() {
            while (!connectedStatus) {
                try {
                    clientSocket = new Socket(ipAddress, 3339);
                    connectedStatus = true;
                    transmitter = new DirectoryTxr(clientSocket, srcPath, dstPath);
                } catch (IOException io) {
                    io.printStackTrace();
                }
            }

        }
    };
    Thread connectionThread = new Thread(connectRunnable);
    connectionThread.start();
}

DirectoryTxr.java

import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class DirectoryTxr {
    Socket clientSocket = null;
    String srcDir = null;
    String dstDir = null;
    byte[] readBuffer = new byte[1024];
    private InputStream inStream = null;
    private OutputStream outStream = null;
    int state = 0;
    final int permissionReqState = 1;
    final int initialState = 0;
    final int dirHeaderSendState = 2;
    final int fileHeaderSendState = 3;
    final int fileSendState = 4;
    final int fileFinishedState = 5;
    private boolean isLive = false;
    private int numFiles = 0;
    private int filePointer = 0;
    String request = "May I send?";
    String respServer = "Yes,You can";
    String dirResponse = "Directory created...Please send files";
    String fileHeaderRecvd = "File header received ...Send File";
    String fileReceived = "File Received";
    String dirFailedResponse = "Failed";
    File[] opFileList = null;

    public DirectoryTxr(Socket clientSocket, String srcDir, String dstDir) {

        try {
            this.clientSocket = clientSocket;
            inStream = clientSocket.getInputStream();
            outStream = clientSocket.getOutputStream();
            isLive = true;
            this.srcDir = srcDir;
            this.dstDir = dstDir;
            state = initialState;
            readResponse(); //starting read thread
            sendMessage(request);
            state = permissionReqState;
        } catch (IOException io) {
            io.printStackTrace();
        }


    }

    private void sendMessage(String message) {
        try {
            sendBytes(request.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }


    /**
     * Thread to read response from server
     */
    private void readResponse() {
        Runnable readRunnable = new Runnable() {
            public void run() {
                while (isLive) {
                    try {
                        int num = inStream.read(readBuffer);
                        if (num > 0) {
                            byte[] tempArray = new byte[num];
                            System.arraycopy(readBuffer, 0, tempArray, 0, num);
                            processBytes(tempArray);
                        }
                    } catch (SocketException se) {
                        System.exit(0);
                    } catch (IOException io) {
                        io.printStackTrace();
                        isLive = false;
                    }
                }
            }
        };
        Thread readThread = new Thread(readRunnable);
        readThread.start();

    }

    private void sendDirectoryHeader() {
        File file = new File(srcDir);
        if (file.isDirectory()) {
            try {
                String[] childFiles = file.list();
                numFiles = childFiles.length;
                String dirHeader = "$" + dstDir + "#" + numFiles + "&";
                sendBytes(dirHeader.getBytes("UTF-8"));
            } catch (UnsupportedEncodingException en) {
                en.printStackTrace();
            }
        } else {
            System.out.println(srcDir + " is not a valid directory");
        }
    }


    private void sendFile(String dirName) {
        File file = new File(dirName);

        if (!file.isDirectory()) {
            try {
                int len = (int) file.length();
                int buffSize = len / 8;
                //to avoid the heap limitation
                RandomAccessFile raf = new RandomAccessFile(file, "rw");
                FileChannel channel = raf.getChannel();

                int numRead = 0;
                while (numRead >= 0) {
                    ByteBuffer buf = ByteBuffer.allocate(1024 * 100000);
                    numRead = channel.read(buf);
                    if (numRead > 0) {
                        byte[] array = new byte[numRead];
                        System.arraycopy(buf.array(), 0, array, 0, numRead);
                        sendBytes(array);
                    }
                }
                System.out.println("Finished");

            } catch (IOException io) {
                io.printStackTrace();
            }

        }

    }

    private void sendHeader(String fileName) {
        try {
            File file = new File(fileName);
            if (file.isDirectory())
                return;//avoiding child directories to avoid confusion
            //if want we can sent them recursively
            //with proper state transitions

            String header = "&" + fileName + "#" + file.length() + "*";
            sendHeader(header);

            sendBytes(header.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private void sendBytes(byte[] dataBytes) {
        synchronized (clientSocket) {
            if (outStream != null) {
                try {
                    outStream.write(dataBytes);
                    outStream.flush();
                } catch (IOException io) {
                    io.printStackTrace();
                }
            }
        }

    }

    private void processBytes(byte[] data) {
        try {
            String parsedMessage = new String(data, "UTF-8");
            System.out.println(parsedMessage);
            setResponse(parsedMessage);
        } catch (UnsupportedEncodingException u) {
            u.printStackTrace();
        }
    }

    private void setResponse(String message) {
        if (message.trim().equalsIgnoreCase(respServer) && state == permissionReqState) {
            state = dirHeaderSendState;
            sendDirectoryHeader();


        } else if (message.trim().equalsIgnoreCase(dirResponse) && state == dirHeaderSendState) {
            state = fileHeaderSendState;
            if (LocateDirectory()) {
                createAndSendHeader();
            } else {
                System.out.println("Vacant or invalid directory");
            }


        } else if (message.trim().equalsIgnoreCase(fileHeaderRecvd) && state == fileHeaderSendState) {
            state = fileSendState;
            sendFile(opFileList[filePointer].toString());
            state = fileFinishedState;
            filePointer++;

        } else if (message.trim().equalsIgnoreCase(fileReceived) && state == fileFinishedState) {
            if (filePointer < numFiles) {
                createAndSendHeader();
            }
            System.out.println("Successfully sent");

        } else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
            System.out.println("Going to exit....Error ");
            // System.exit(0);
        } else if (message.trim().equalsIgnoreCase("Thanks")) {
            System.out.println("All files were copied");
        }

    }

    private void closeSocket() {
        try {
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private boolean LocateDirectory() {
        boolean status = false;
        File file = new File(srcDir);
        if (file.isDirectory()) {
            opFileList = file.listFiles();
            numFiles = opFileList.length;
            if (numFiles <= 0) {
                System.out.println("No files found");
            } else {
                status = true;
            }

        }
        return status;
    }

    private void createAndSendHeader() {
        File opFile = opFileList[filePointer];
        String header = "&" + opFile.getName() + "#" + opFile.length() + "*";
        try {
            state = fileHeaderSendState;
            sendBytes(header.getBytes("UTF-8"));

        } catch (UnsupportedEncodingException e) {

        }
    }

    private void sendListFiles() {
        createAndSendHeader();

    }
}

ServerMain.java

public class ServerMain {

    public ServerMain() {

    }

    public static void main(String[] args) {

        DirectoryRcr dirRcr = new DirectoryRcr();

    }
}

目录Rcr.java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;


public class DirectoryRcr {

    String request = "May I send?";
    String respServer = "Yes,You can";
    String dirResponse = "Directory created...Please send files";
    String dirFailedResponse = "Failed";
    String fileHeaderRecvd = "File header received ...Send File";
    String fileReceived = "File Received";
    Socket socket = null;
    OutputStream ioStream = null;
    InputStream inStream = null;
    boolean isLive = false;
    int state = 0;
    final int initialState = 0;
    final int dirHeaderWait = 1;
    final int dirWaitState = 2;
    final int fileHeaderWaitState = 3;
    final int fileContentWaitState = 4;
    final int fileReceiveState = 5;
    final int fileReceivedState = 6;
    final int finalState = 7;
    byte[] readBuffer = new byte[1024 * 100000];
    long fileSize = 0;
    String dir = "";
    FileOutputStream foStream = null;
    int fileCount = 0;
    File dstFile = null;

    public DirectoryRcr() {
        acceptConnection();
    }

    private void acceptConnection() {
        try {
            ServerSocket server = new ServerSocket(3339);
            socket = server.accept();
            isLive = true;
            ioStream = socket.getOutputStream();
            inStream = socket.getInputStream();
            state = initialState;
            startReadThread();

        } catch (IOException io) {
            io.printStackTrace();
        }
    }

    private void startReadThread() {
        Thread readRunnable = new Thread() {
            public void run() {
                while (isLive) {
                    try {
                        int num = inStream.read(readBuffer);
                        if (num > 0) {
                            byte[] tempArray = new byte[num];
                            System.arraycopy(readBuffer, 0, tempArray, 0, num);
                            processBytes(tempArray);
                        }
                        sleep(100);

                    } catch (SocketException s) {

                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException i) {
                        i.printStackTrace();
                    }
                }
            }
        };
        Thread readThread = new Thread(readRunnable);
        readThread.start();
    }

    private void processBytes(byte[] buff) throws InterruptedException {
        if (state == fileReceiveState || state == fileContentWaitState) {
            //write to file
            if (state == fileContentWaitState)
                state = fileReceiveState;
            fileSize = fileSize - buff.length;
            writeToFile(buff);


            if (fileSize == 0) {
                state = fileReceivedState;
                try {
                    foStream.close();
                } catch (IOException io) {
                    io.printStackTrace();
                }
                System.out.println("Received " + dstFile.getName());
                sendResponse(fileReceived);
                fileCount--;
                if (fileCount != 0) {
                    state = fileHeaderWaitState;
                } else {
                    System.out.println("Finished");
                    state = finalState;
                    sendResponse("Thanks");
                    Thread.sleep(2000);
                    System.exit(0);
                }

                System.out.println("Received");
            }
        } else {
            parseToUTF(buff);
        }

    }

    private void parseToUTF(byte[] data) {
        try {
            String parsedMessage = new String(data, "UTF-8");
            System.out.println(parsedMessage);
            setResponse(parsedMessage);
        } catch (UnsupportedEncodingException u) {
            u.printStackTrace();
        }

    }

    private void setResponse(String message) {
        if (message.trim().equalsIgnoreCase(request) && state == initialState) {
            sendResponse(respServer);
            state = dirHeaderWait;

        } else if (state == dirHeaderWait) {
            if (createDirectory(message)) {
                sendResponse(dirResponse);
                state = fileHeaderWaitState;
            } else {
                sendResponse(dirFailedResponse);
                System.out.println("Error occurred...Going to exit");
                System.exit(0);
            }


        } else if (state == fileHeaderWaitState) {
            createFile(message);
            state = fileContentWaitState;
            sendResponse(fileHeaderRecvd);

        } else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
            System.out.println("Error occurred ....");
            System.exit(0);
        }

    }

    private void sendResponse(String resp) {
        try {
            sendBytes(resp.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private boolean createDirectory(String dirName) {
        boolean status = false;
        dir = dirName.substring(dirName.indexOf("$") + 1, dirName.indexOf("#"));
        fileCount = Integer.parseInt(dirName.substring(dirName.indexOf("#") + 1, dirName.indexOf("&")));
        if (new File(dir).mkdir()) {
            status = true;
            System.out.println("Successfully created directory  " + dirName);
        } else if (new File(dir).mkdirs()) {
            status = true;
            System.out.println("Directories were created " + dirName);

        } else if (new File(dir).exists()) {
            status = true;
            System.out.println("Directory exists" + dirName);
        } else {
            System.out.println("Could not create directory " + dirName);
            status = false;
        }

        return status;
    }

    private void createFile(String fileName) {

        String file = fileName.substring(fileName.indexOf("&") + 1, fileName.indexOf("#"));
        String lengthFile = fileName.substring(fileName.indexOf("#") + 1, fileName.indexOf("*"));
        fileSize = Integer.parseInt(lengthFile);
        dstFile = new File(dir + "/" + file);
        try {
            foStream = new FileOutputStream(dstFile);
            System.out.println("Starting to receive " + dstFile.getName());
        } catch (FileNotFoundException fn) {
            fn.printStackTrace();
        }

    }

    private void writeToFile(byte[] buff) {
        try {
            foStream.write(buff);
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

    private void sendBytes(byte[] dataBytes) {
        synchronized (socket) {
            if (ioStream != null) {
                try {
                    ioStream.write(dataBytes);
                } catch (IOException io) {
                    io.printStackTrace();
                }
            }
        }

    }

客户端应用程序包含两个类 ClientMain.java 和 DirectoryTxr.java 服务器应用程序包含两个类 ServerMain.java 和 DirectoryRcr.java

我创建进度条的代码也是

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class ProgressBar extends JFrame {
 JProgressBar current = new JProgressBar(0, 2000);
 int num = 0;

 public ProgressBar() {
  //exit button
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  //create the panel to add the details
  JPanel pane = new JPanel();
  current.setValue(0);
  current.setStringPainted(true);
  pane.add(current);
  setContentPane(pane);
 }

 //to iterate so that it looks like progress bar  
 public void iterate() {
  while (num < 2000) {
   current.setValue(num);
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
   }
   num += 95;
  }
 }

 //for testing the app
 public static void main(String[] arguments) {
  ProgressBar frame = new ProgressBar();
  frame.pack();
  frame.setVisible(true);
  frame.iterate();
 }
}
4

2 回答 2

2

查看ProgressMonitorInputStreamSwing 教程中的使用进度条

于 2013-06-14T05:03:59.140 回答
1

Swing 是一个单线程框架。这意味着与 UI 的所有交互都应在此线程(AKA 事件调度线程)的上下文中进行。

这也意味着,如果您在 EDT 中执行任何类型的耗时/长时间运行或阻塞进程,您将阻止它响应事件或更新 UI。

这就是您的代码当前正在执行的操作。

您可以使用多种机制来克服这个问题,在您的情况下,最简单的可能是使用SwingWorker

import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ProgressBar extends JFrame {

    JProgressBar current = new JProgressBar(0, 100);
    int num = 0;

    public ProgressBar() {
        //exit button
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //create the panel to add the details
        JPanel pane = new JPanel();
        current.setValue(0);
        current.setStringPainted(true);
        pane.add(current);
        setContentPane(pane);
    }

    //to iterate so that it looks like progress bar  
    public void iterate() {
        SwingWorker worker = new SwingWorker<Object, Object>() {
            @Override
            protected Object doInBackground() throws Exception {
                while (num < 2000) {
//                    current.setValue(num);
                    try {
                        Thread.sleep(125);
                    } catch (InterruptedException e) {
                    }
                    num += 95;
                    int p = Math.round(((float)Math.min(num, 2000) / 2000f) * 100f);
                    setProgress(p);
                }
                return null;
            }
        };
        worker.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                String name = evt.getPropertyName();
                if ("progress".equals(name)) {
                    SwingWorker worker = (SwingWorker) evt.getSource();
                    current.setValue(worker.getProgress());
                }
            }
        });
        worker.execute();
    }

    //for testing the app
    public static void main(String[] arguments) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                ProgressBar frame = new ProgressBar();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.iterate();
            }
        });
    }
}

查看http://docs.oracle.com/javase/tutorial/uiswing/concurrency/了解更多详情。

更新了双焊接进度条的示例

如果您需要显示多个进度条,您可以简单地使用publishprocess方法SwingWorker来完成更复杂的结果...

在此处输入图像描述

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

 */
public class ProgressBar extends JFrame {

    JProgressBar current = new JProgressBar(0, 100);
    JProgressBar overall = new JProgressBar(0, 100);
    int num = 0;

    public ProgressBar() {
        //exit button
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //create the panel to add the details
        JPanel pane = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        current.setValue(0);
        current.setStringPainted(true);
        overall.setStringPainted(true);
        pane.add(overall, gbc);
        pane.add(current, gbc);
        setContentPane(pane);
    }

    //to iterate so that it looks like progress bar  
    public void iterate() {
        SwingWorker worker = new SwingWorker<Object, float[]>() {

            @Override
            protected void process(List<float[]> chunks) {
                float[] progress = chunks.get(chunks.size() - 1); // only want the last one
                overall.setValue(Math.round(progress[0] * 100f));
                current.setValue(Math.round(progress[1] * 100f));
            }

            @Override
            protected Object doInBackground() throws Exception {
                int size = 2000;
                int overallSize = size * 10;
                int overallProgress = 0;
                for (int index = 0; index < 10; index++) {
                    for (int count = 0; count < size; count++) {
                        publish(new float[]{
                            getProgress(overallProgress, overallSize),
                            getProgress(count, size),
                        });
                        overallProgress++;
                        Thread.sleep(2);
                    }
                }
                return null;
            }

            public float getProgress(int value, int max) {

                return (float)value / (float)max;

            }
        };
        worker.execute();
    }

    //for testing the app
    public static void main(String[] arguments) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                ProgressBar frame = new ProgressBar();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.iterate();
            }
        });
    }
}
于 2013-06-14T05:35:48.547 回答