1

テキスト ファイル内のすべての行を読み取るメソッドがあり、読み取られたファイルの現在の割合を出力したいと考えています。私はこれを行うことができましたが、新しい行を読み取るたびにパーセンテージを出力するため、出力は次のようになります。

0.0% 読み取り。
0.0% 読み取り。
0.0% 読み取り。
1.0% 読み取り。
1.0% 読み取り。
1.0% 読み取り。

など... 0から1、1から2などに変化するたびに出力したい。コードの関連部分は次のとおりです。

BufferedReader reader = new BufferedReader(new InputStreamReader(
        new FileInputStream(file), "UTF-8"));
String line = reader.readLine();
// Counts total number of lines
BufferedReader reader2 = new BufferedReader(new InputStreamReader(
        new FileInputStream(file), "UTF-8"));
int totalLines = 0;
while (reader2.readLine() != null) {
    totalLines++;
}
// read all lines from file
int lineNumber = 1;
while (line != null) {
    float percent = lineNumber * 100f / totalLines;
    double x = Math.round(percent);
    System.out.println(x + "% read.");
    line = reader.readLine();
    lineNumber++;
}
4

3 に答える 3

7

前の値を保存する

以下のコード スニペットでは、float 変数previousPercent. これは、ループの先頭で宣言できます。previousPercentループごとに新しい値で更新します。ループ内で 2 つの値が異なる場合は値を出力し、それ以外の場合は単に update を実行しpreviousPercentます。

float percent = (float)Math.floor(lineNumber * 100f / totalLines);
// Compute your percentage.
if(percent != previousPercent)
{
    // Output if different from the last time.
    System.out.println(percent + "% read");
}
// Update the percentage.
previousPercent = percent;

パーセンテージに関するメモ

コメントで述べたように、パーセンテージを四捨五入することをお勧めします。これは、最も小さな変更が出力につながるためです。Math.floor()and notを使用する理由は、ファイルMath.round()を読んだとしましょう。6.7%あなたは言うことを正当化することができ6% readますが、あなたは読んでいません7%

于 2013-05-13T12:07:07.370 に答える
2

それを機能させるには、現在のパーセンテージを前回の反復からのパーセンテージと照合する必要があります。うまく機能させるには、数ではなくバイト数でパーセンテージを計算する必要があります。

バイトを使用すると、次のことができます。

  • ファイルを 2 回ロード/読み取りしないようにします。これにより、実行時間がほぼ2 倍になります。
  • 各行に読み取られた実際のバイト数を使用して、より正確なパーセンテージを提供します (1 つの大きな行が 100 の小さな行としてカウントされるなど)。

これを 100MB のファイルで実行し、実行時間を調べます。

(最初の方法は JVM ウォームアップも行っていることに注意してください)

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Date;

public class FilePercentageTest {

    public static void main(String[] args) throws java.lang.Exception {
        File file = new File("D:/test.txt");

        showPercentageByBytes(file);
        showPercentageByLines(file);

    }

    private static void showPercentageByBytes(File file) throws Exception{
        long start = new Date().getTime();          
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                new FileInputStream(file), "UTF-8"));               
        long totalBytes = file.length();                    
        long bytesRead = 0;
        int previousPercent = 0;
        String line = reader.readLine();
        while (line != null) {          
            bytesRead+=line.length();
            int percent = (int)(bytesRead * 100 / totalBytes);          
            if (previousPercent<percent){
                System.out.println(percent + "% read.");            
                previousPercent = percent;
            }
            line = reader.readLine();
        }       
        long end = new Date().getTime();            
        System.out.println(end - start + " milliseconds ");
    }


    private static void showPercentageByLines(File file) throws Exception{
        long start = new Date().getTime();          
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                new FileInputStream(file), "UTF-8"));
        String line = reader.readLine();
        BufferedReader reader2 = new BufferedReader(new InputStreamReader(
                new FileInputStream(file), "UTF-8"));
        int totalLines = 0;
        int previousPercent = 0;
        while (reader2.readLine() != null) {
            totalLines++;
        }
        int lineNumber = 1;
        while (line != null) {
            int percent = lineNumber * 100 / totalLines;
            if (previousPercent<percent){
                System.out.println(percent + "% read.");            
                previousPercent = percent;
            }
            line = reader.readLine();
            lineNumber++;
        }       
        long end = new Date().getTime();            
        System.out.println(end - start + " milliseconds ");
    }
}
于 2013-05-13T12:50:18.013 に答える
0
double x = 0;
while(line != null) {

    float percent = lineNumber * 100f / totalLines;
    if (Math.round(percent) != x) {
         System.out.println(x + "% read.");
         x = Math.round(percent);
    }
    line = reader.readLine();

    lineNumber++;   
}
于 2013-05-13T12:08:15.900 に答える