2013-11-07 1 views
0

Я читаю файл, используя BufferedReader, файл представляет собой текстовый файл с большим количеством текстаКак отслеживать чтение файла с помощью .readLine() в java?

вот как я читаю его

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; 
         } 
       } 
+0

Увеличение количества строк, прочитанных до сих пор после каждого readLine() и деления его на общее число строк в вашем файле –

+0

есть ли способ получить общее количество строк в моем файле ? – Snedden27

+0

http://stackoverflow.com/questions/9691420/api-for-simple-file-line-count-functions-in-java –

ответ

2

Есть любое количество способов для достижения этой цели, но вы должны держать четыре вещи в виде ...

  1. Вы должны знать, сколько вы читаете
  2. Вы должны знать, сколько вы читали
  3. Вы никогда не должны выполнять какие-либо действия в контексте событий диспетчерской темы, которая может блокировать его (например, если работает петлю или блокирование ввода/вывод)
  4. Вы никогда не должны изменять или изменять состояние пользовательского интерфейса из любого другого потока, то событие Диспетчерским Пропусти

этого пример просто использует SwingWorker для чтения файла в фоновом режиме Автошоу объявление и использует его функции прогресса, чтобы отправлять обновления обратно в контекст 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», а также. Взгляните на Concurrency in Swing для получения более подробной информации.

3

используйте FileInputStream, javax.swing.ProgressMonitorInputStream, InputStreamReader и BufferedReader. Затем все происходит автоматически.

+0

проблема в том, что он открывает свой собственный индикатор выполнения, я хочу добавить значение на индикатор выполнения я установил – Snedden27

+0

+1 Whoa! Никогда не слышал о «ProgressMonitorInputStream» раньше. –

+0

@ Snedden27 Не беспокойтесь. Используйте то, что встроено. – EJP

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; 
     } 

    } 

затем просто использовать стандартные методы геттер. Вы можете получить максимум, используя myInputStream.availble();

ссылку на соответствующий исходный код: http://developer.classpath.org/doc/javax/swing/ProgressMonitorInputStream-source.html

+0

Я не верю, что 'availble' является надежной мерой для общего содержимого, которое может появиться через входной поток. – MadProgrammer

+0

Вот что класс ProgressMonitorInputStream использует хотя. – Skylion

+0

Из JavaDocs * «Возвращает оценку количества байтов, которые могут быть прочитаны (или пропущены) из этого входного потока без блокировки путем следующего вызова метода для этого входного потока» * - Файловые потоки могут быть разными, I 'm just say;) – MadProgrammer

0

Как быстро «взломать» вы можете реализовать подсчет FilterInputStream, и использовать его таким образом, что EJP предлагает:

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; 
    } 

} 

Тогда ваш код может делать:

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..... 
} 
+0

Спасибо, что нарушили правила единственной нити Swing ... – MadProgrammer

+0

Да, скопируйте/вставьте из OP, не очень умный ....... починю. – rolfl