DataOutputStream写入进度不准确

时间:2014-04-30 12:31:23

标签: java android

DataOutputStream wr = new DataOutputStream(
                    urlConnection.getOutputStream());
            fis = new FileInputStream(image_path);
            int total = 0;
            int bytes_read = 0;
            int buffer_size = 1024;
            byte[] buffer = new byte[buffer_size];
            bytes_read = fis.read(buffer, 0, buffer_size);
            int progress = 0;
            while (bytes_read > 0) {
                total += bytes_read;
                wr.write(buffer, 0, bytes_read);
                int bytes_available = fis.available();
                progress = (int) ((total * 100) / bytes.length);
                Log.i("asd", "direct progress: " + progress);
                buffer_size = Math.min(bytes_available, buffer_size);
                buffer = new byte[buffer_size];
                bytes_read = fis.read(buffer, 0, buffer_size);
            }
            Log.i("asd", "data written to target so far is: " + wr.size()+ " file length: "+bytes.length);
            wr.flush();
            wr.close();

将文件完全上传到服务器上。但我的目的是获得已经上传的字节的进度。我也可以得到它(我认为这是不准确的)。 当我运行此代码时,它显示从0到100的进度,但文件在1分钟左右后上传到服务器。

我尝试使用小于1MB的文件,但进度是准确的。但是当文件较大时,我会得到进度问题的不准确性。

2 个答案:

答案 0 :(得分:2)

您的进度指示器不准确,因为您将(读取的字节数)除以(在一次读取中读取的字节数)。这意味着您显示的读取次数为上载百分比,这是不正确的,仅适用于以100次读/写方式上传的文件。

您应该在开头阅读一次文件长度。然后累积读/写的总字节数。然后进步等于:

progress = 100 * totalBytesWritten / fileLength

DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
fis = new FileInputStream(image_path);
int fileLength = new File(image_path).length();

int bytes_read = 0;
int bytesReadTotal = 0;
int buffer_size = 1024;
byte[] buffer = new byte[buffer_size];
int progress = 0;

while ((bytes_read = fis.read(buffer, 0, buffer_size)) > 0) {
     wr.write(buffer, 0, bytes_read);
     bytesReadTotal += bytes_read;
     progress = (int) (100.0f * bytesReadTotal / fileLength);
     Log.i("asd", "direct progress: " + progress);
}
Log.i("asd", "data written to target so far is: " + wr.size()+ " file length: "+bytes.length);
wr.flush();
wr.close();

每次您想要读/写某些内容时,您也不必重新创建缓冲区。您可以重复使用旧的。

答案 1 :(得分:1)

connection.setFixedLengthStreamingMode((int) requestLength);

会做到这一点!