JAVA BufferedOutputStream медленно сбрасывается с правильным размером файла - PullRequest
0 голосов
/ 27 апреля 2011

Я использую BufferedOutputStream для записи в файл.Во время отладки я заметил, что операция очистки занимает очень много времени, даже если ОС показывает, что файл имеет окончательный размер.

Моя теория: BufferedOutputStream сообщает ОС заранее резервировать место?Таким образом, ОС уже показывает файл с полным размером файла, даже если BufferedOutputStream еще не полностью очищен?

Это правильно?

Ответы [ 3 ]

2 голосов
/ 27 апреля 2011

BufferedOutputStream поддерживает собственный внутренний буфер byte[].Глядя на реализацию кода , он просто заполняет этот буфер перед записью его в основной поток.Документация не дает гораздо большей помощи.

Я не думаю, что вы можете сделать больше предположений, чем это, не глядя на собственные реализации на каждой платформе.Если вы хотите получить больше подробностей, вы можете запустить что-то вроде strace и проверить, что происходит с простой программой.

Я написал следующую простую программу

import java.io.*;

public class Test {
    public static void main(String args[]) throws Exception {
        File f = new File("test.txt");
        FileOutputStream fos = new FileOutputStream(f);
        BufferedOutputStream bos = new BufferedOutputStream(fos, 16384);
        for (int i=0;i<10000;++i) {
            bos.write(new byte[1024]);
        }
    }
}

И побежал strace на нем.Убедитесь, что вы используете флаг -f для отслеживания дочерних процессов.Отфильтрованная копия того, что было запущено, показана ниже.

[pid  6394] mprotect(0x7fdebc03e000, 4096, PROT_READ|PROT_WRITE) = 0
[pid  6394] open("test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
[pid  6394] fstat(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid  6394] mprotect(0x7fdebc03f000, 16384, PROT_READ|PROT_WRITE) = 0
[pid  6394] write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\"...,    16384) = 16384
[pid  6394] write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\"...,    16384) = 16384
[pid  6394] write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\"...,    16384) = 16384

Я не вижу никаких вызовов зарезервировать место заранее (обратите внимание, что вы абсолютно уверены в mprotect , но это не имеет отношения).Поведение, которое я вижу на моем компьютере с Linux, - это просто заполнение буфера и запись на диск.

0 голосов
/ 05 июня 2012

Проверьте свой антивирусный сканер. Иногда это замедляет запись в файл.

0 голосов
/ 27 апреля 2011

Является ли это случаем, что ваша файловая система является удаленной, и поэтому вызов flush передает данные через сеть (и хост с другой стороны может решить на самом деле «зарезервировать» требуемое файловое пространство, как вы его указали и толькозаписать байты на диск, как только он получит все байты)?Или вы используете локальную файловую систему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...