0

我正在使用 bufferedREader 读取文件,该文件是一个包含大量文本的文本文件

这是我的阅读方式

 while(true)  //I know the loop is not perfect just ignore it for now, i wanna concentrate on the tracking
                {
                      try
                      {
                       br.readLine();
                      }
                      catch(IOException e)
                      {
                      break;
                      }
                      catch (Exception e)
                      {
                      break;
                      }
                }

我想跟踪我读过的文件的百分比,这样我就可以在进度条中使用该百分比值,如下所示:

while(true)
                {
                      try
                      {
                       br.readLine();
                       progressBar.setValue(percentageRead);//how do I get percentageRead value dynamically?
                      }
                      catch(IOException e)
                      {
                      break;
                      }
                      catch (Exception e)
                      {
                      break;
                      }
                }
4

4 回答 4

3

使用 FileInputStream、javax.swing.ProgressMonitorInputStream、InputStreamReader 和 BufferedReader。然后这一切都会自动发生。

于 2013-11-07T02:01:36.060 回答
2

有很多方法可以实现这一点,但你需要记住四件事......

  1. 你需要知道你读了多少
  2. 你需要知道你读了多少
  3. 你不应该在事件调度线程的上下文中执行任何可能阻塞它的操作(例如长时间运行的循环或阻塞 I/O)
  4. 您不应该从除事件调度线程之外的任何线程修改或更改 UI 的状态

此示例仅使用 aSwingWorker在后台线程中读取文件,并使用它的进度功能将更新发布回 EDT 的上下文。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ReadFile {

    public static void main(String[] args) {
        new ReadFile();
    }

    public ReadFile() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                final JProgressBar pb = new JProgressBar(0, 100);
                final ReadFileWorker worker = new ReadFileWorker();
                worker.addPropertyChangeListener(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                            pb.setValue(worker.getProgress());
                        }
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(pb);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                worker.execute();
            }
        });
    }

    public class ReadFileWorker extends SwingWorker<List<String>, String> {

        @Override
        protected List<String> doInBackground() throws Exception {
            List<String> lines = new ArrayList<>(25);
            File textFile = new File("Test.txt");
            long byteLength = textFile.length();

            System.out.println("Reading " + byteLength + " bytes...");

            try (InputStream is = new FileInputStream(textFile)) {

                byte[] content = new byte[1024];
                int bytesRead = -1;
                long totalBytes = 0;
                String lastText = "";
                while ((bytesRead = is.read(content)) != -1) {

                    totalBytes += bytesRead;
                    setProgress(Math.round(((float) totalBytes / (float) byteLength) * 100f));

                    String text = lastText + new String(content);
                    boolean keepEnd = !text.endsWith("\n");
                    String[] parts = text.split("\n");

                    for (int count = 0; count < (keepEnd ? parts.length - 1 : parts.length); count++) {
                        lines.add(parts[count]);
                        publish(parts[count]);
                    }

                    if (keepEnd) {
                        lastText = parts[parts.length - 1];
                    } else {
                        lastText = "";
                    }

                    // This is only here to slow the demonstration down
                    Thread.sleep(5);

                }

                System.out.println("Read " + totalBytes + " bytes...");
                System.out.println("Read " + lines.size() + " lines...");

            } finally {

            }

            return lines;
        }

        @Override
        protected void done() {
            try {
                List<String> lines = get();
            } catch (InterruptedException | ExecutionException ex) {
                ex.printStackTrace();
            }
        }

    }

}

现在,您也可以将其SwingWorker与其他“ProgressInputStream”实现之一合并。查看Swing 中的并发以获取更多详细信息

于 2013-11-07T02:31:44.997 回答
0

As a quick 'hack' you can implement a counting FilterInputStream, and use it in a way that EJP suggests:

public class ProgressInputStream extends FilterInputStream {

    private final double maxbytes;
    private long current = 0;

    public ProgressInputStream(InputStream in, long bytestoexpect) {
        super(in);
        maxbytes = (double)bytestoexpect;
    }

    /**
     * return a value between 0.0 and 1.0 to represent the progress.
     * should do some division-by-zero checking here too.
     */
    public double getProgress() {
        return current / maxbytes;
    }

    @Override
    public int read() throws IOException {
        final int ret = super.read();
        if (ret >= 0) {
            current++;
        }
        return ret;
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        final int ret = super.read(b, off, len);
        current += ret;
        return ret;
    }

    @Override
    public int read(byte[] b) throws IOException {
        // TODO Auto-generated method stub
        final int ret = super.read(b);
        current += ret;
        return ret;
    }

    @Override
    public long skip(long n) throws IOException {
        final long ret = super.skip(n);
        current += ret;
        return ret;
    }

}

Then, your code can do:

final File infile = new File("path/to/file");
final long insize = infile.length();
final ProgresInputStream pis = new ProgressInputStream(new FileInputStream(infile), insize);
BufferedReader br = new BufferedReader(new InputStreamReader(pis));
String line = null;
try {
    while((line = br.readLine()) != null) {
        final int pct = (int)(pis.getProgress() * 100.0);
        // assume progressbar is final, etc.
        SwingUtilities.invokeLater(new Runnable() {
           public void run() {
                progressBar.setValue(pct);
           }
        });
    }
} catch(IOException e) {
    // do proper handling here.....
}
于 2013-11-07T02:25:41.710 回答
0

简单的

private class myProgressBar{
     private int read;

     //override constructor and such... 

     @Override 
     public int read(byte[] data, int offset, int length) throws IOException
      {
        int t = super.read(data, offset, length);
        if ( t > 0 )
        {
         read += t;
        }
        return t;
       }

  }

然后只需使用标准的 getter 方法。您可以使用 myInputStream.availble(); 获得最大值

相关源代码链接:http: //developer.classpath.org/doc/javax/swing/ProgressMonitorInputStream-source.html

于 2013-11-07T02:20:35.473 回答