Set progress bar value according to the unknown length of text file
I currently 开发者_JAVA百科have a program which reads from a text file and then writes to a database after each line it reads, the size of the text file is undetermined, some days the file could be more or less lines than other days.
I already have a swing worker that executes my functions so my progress bar works but right now I just have setIndeterminate
to true
so the user knows something is being done just not the actual progress.
Is there a way I can increment the progress bar after each line is read, but have it not reach 100 too early or too late, preferably without reading the the text file entirely before hand. Thanks, Beef.
I'd use File.length() to determine the file size. Then keep track of the number of bytes read to determine the progress.
If the file size is known before you are starting to read it you can read it line-by-line and count the percentage after every line: count the number of bytes in each line and devide it by the total number of bytes (i.e. file.length()
).
and wrap output to the GUI (in your case the Progress
from the JProgressBar
) to the invokeLater()
, because you are pretty out of the EDT, more in Concurency in Swing
To determine the file size is easy using java.io.File
so the problem here is to get the size in bytes actually read for a simple progress bar two possibilities come to mind:
Estimation: Assume 1 Character = 1 Byte (or 1 Character = 2 Byte if your file is UTF-16,...). The 1 Byte guess will have you underestimate your actual size read so you will have a jump of the bar at the end depending on how many multi byte characters are in your file.
Calculate: Recode the characters read to a byte array using the files character encoding and take the length of the encoded array.
Count: As proposed by Brendan in the comments below, use a
CountingInputStream
(in correct order after Buffering) to count the bytes actually read.
Nr. 2. seems unneccessary overhead for this case to me so I think I'd stick to Nr. 1 or Nr. 3
You can have in your app something like this image :)
精彩评论