【问题标题】:ProgressMonitorInputStream in Socket ProgrammingSocket 编程中的 ProgressMonitorInputStream
【发布时间】:2014-05-03 07:08:39
【问题描述】:

我有一个套接字连接的客户端和服务器。我尝试将 progressMonitorInputStream() 实现到服务器,数据传输完美,但进度监视器不可见。我尝试实现它以仅从一侧读取文件,进度监视器工作正常。以下是两个代码

服务器:

    public class Server implements ActionListener, PropertyChangeListener {

    DataInputStream dis;
    ProgressMonitor pm;
    ProgressMonitorInputStream pmis;
    JFrame frm;
    Server s;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                new Server().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        frm = new JFrame();
        JPanel panel = new JPanel();

        JButton st = new JButton("Start");

        st.setPreferredSize(new Dimension(80, 25));

        panel.add(st);

        panel.setSize(500, 50);

        frm.add(panel);
        frm.setLocationRelativeTo(null);
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.pack();
        frm.show();

        st.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        frm.dispose();
        try {
            ServerSocket ss = new ServerSocket(5555);
            Socket soc = ss.accept();
            dis = new DataInputStream(soc.getInputStream());
            pmis = new ProgressMonitorInputStream(frm, "Progress", dis);
            pm = pmis.getProgressMonitor();
//            pm.setMillisToPopup(1);
            Task task = new Task();
            task.addPropertyChangeListener(s);
            task.execute();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if ("progress".equals(evt.getPropertyName())) {
            int progress = (Integer) evt.getNewValue();
            pm.setProgress(progress);

        }
    }

    class Task extends SwingWorker<Void, Void> {

        @Override
        protected Void doInBackground() throws Exception {
            int progress = 0;
            setProgress(0);
            int x;
            while ((x = pmis.read()) != -1) {
                System.out.print((char) x);
                setProgress(progress);
                progress++;                
            }
            pmis.close();
            return null;
        }

        @Override
        public void done() {
            pm.close();
        }        

    }
}

上面的代码是有问题的。工作代码如下:

一侧带有文件输入流的正确工作代码

    public class ProgressMonitorOwn implements ActionListener,
        PropertyChangeListener {

    JFrame frm;
    Task task;
    DataInputStream dis;
    ProgressMonitorInputStream pmis;
    JButton but;
    ProgressMonitor pm;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ProgressMonitorOwn().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        frm = new JFrame();
        JPanel panel = new JPanel();
        but = new JButton("Show");
        but.setPreferredSize(new Dimension(100, 25));

        panel.add(but);
        panel.setSize(200, 100);

        frm.add(panel);
        frm.setSize(200, 100);
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.setLocationRelativeTo(null);
        frm.show();
        but.addActionListener(this);
    }

    class Task extends SwingWorker<Void, Void> {

        @Override
        protected Void doInBackground() throws Exception {
            int x;
            int prog = 0;
            while ((x = pmis.read()) != -1) {
                System.out.print((char) x);
                setProgress(prog);
                Thread.sleep(100);
                prog++;
            }
            return null;

        }

        @Override
        public void done() {
            but.setEnabled(true);
            pm.close();
            System.exit(0);
        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {

        but.setEnabled(false);
        try {
            FileInputStream fis = new FileInputStream("D:\\test\\test.txt");
            dis = new DataInputStream(fis);
            pmis = new ProgressMonitorInputStream(frm, "ProgressTest", dis);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        task = new Task();
        task.addPropertyChangeListener(this);
        task.execute();
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if ("progress" .equals(evt.getPropertyName())) {
            int progress = (Integer) evt.getNewValue();
            pm = pmis.getProgressMonitor();
            pm.setProgress(progress);
        }
    }
}

我无法弄清楚为什么进度监视器显示在 FileInputStream 程序中而不是套接字程序中。有什么想法吗?

【问题讨论】:

    标签: java sockets progressmonitor


    【解决方案1】:

    您需要在ProgressMonitorInputStreamProgressMonitor 上调用setMaximum() 以达到预期的下载大小。否则它不知道“进步”是什么意思。

    您不必使用ProgressMonitorInputStream 致电setProgress()。它会自动执行此操作。

    你不需要DataInputStream.

    您一次应该读取多个字节。读入byte[] 缓冲区。

    【讨论】:

    • 我认为我们将 ProgressMonitor 用于未知大小的文件。如果我错了,请纠正我。我试过不使用 setProgress(),它没有用。我正在传输字符串,因此我将 DataInputStream 用于 readUTF()。如果我读取将字符串转换为字节 [] 的字节,我将不得不将它们转换回来,对吗?为了完成这样的过程,我可以使用 DataInputStream 轻松传输字符串。我想知道你为什么在我们可以传输字符串时建议使用 byte[]。
    • @Parthe 我不知道你的第一句话是什么意思。我尝试调用setMaximum() 并没有调用setProgress(),它确实有效。如果您要在其上调用方法,您的DataInputStream 应该高于ProgressMonitorInputStream,否则ProgressMonitor 不可能知道正在取得的任何进展。我建议调用read(byte[]) 而不是单字节read(),这是您发布的代码所展示的全部内容。我无法评论您尚未发布的代码。
    • 我尝试覆盖DataInputStream 覆盖ProgressMonitorInputStream,但同样的问题再次发生,进度监视器没有显示。我看到一些链接的代码与 InputStreams 覆盖 ProgressMonitorInputStream。我复制粘贴了代码,但进度监视器没有显示。如果您知道您编辑的一些工作代码,请告诉我,我理解您所说的 read(byte[]) 的意思。我会执行的。
    • 我转换成read(byte[])但是有一个新问题,最后2个或者那里的字符串带有一个额外的'e'。
    • 好问题。我没有答案,只是说如果你在用户面前下载一个那么大的文件,那么显示进度可能根本没有用,因为这需要几个小时。
    【解决方案2】:

    调用frm.setVisible(true); 使可见。更改两个类。

    删除frm.show(),因为它是一种已弃用的方法。看这里Component#show()

    示例代码:

    private void createAndShowUI() {
       frm = new JFrame();
       ...
       // call in the end after adding all the components
       frm.setVisible(true);
    }
    

    【讨论】:

    • 试过了。没用。我在 Server 类中使用的框架只是为了显示“开始”按钮。我什么都不做,进度监视器没有 show() 或 setVisible()。我的问题是进度监视器没有显示。
    • 查看createAndShowUI() 方法,您在其中创建了JFrame
    • 那个框架只包含一个按钮。它显示没有问题。我也应该调用 setVisible 吗?
    • @Parthe 您的实际问题是什么?根据您的问题,您说进度监视器不可见
    • 是的,进度监视器不可见。我尝试调用 setVisible(true)。没有改变。您提到的框架包含一个面板,该面板有一个按钮。我从 ProgressMonitorInputStream 获取进度监视器,这与 JFrame 无关。
    猜你喜欢
    • 2013-12-16
    • 2020-11-02
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 2012-11-11
    相关资源
    最近更新 更多