Inputstream и Outputstream с чтением списка файлов

#java #inputstream #fileoutputstream

#java #входной поток #fileoutputstream

Вопрос:

У меня есть этот список файлов ArrayList

 for(File file : files){

    InputStream in = FileInputStream(file);
    // process each file and save it to file
    OutputStream out = FileOutputStream(file);
    try{

    } finally {
       in.close();
       out.close();
    }
}
  

производительность действительно низкая, поскольку в каждом цикле есть in / out close(), есть ли лучший способ сделать это? Я попытался вывести outputstream из цикла, это не работает.

Комментарии:

1. хм… но, по крайней мере, это должно быть быстрее, когда несколько файлов читаются одновременно … в разных потоках… если вы читаете много файлов.. тогда это должно иметь смысл

2. (Что произойдет, если вы new FileOutputStream создадите исключение (возможно, FileNotFoundException но, возможно, непроверенное исключение)? То же самое для in.close(); . Требуется по одному try finally на ресурс.)

Ответ №1:

Использование буферизованных потоков имеет огромную разницу.

Попробуйте это:

 for(final File file : files) {

    final InputStream in = new BufferedInputStream(new FileInputStream(file));
    final OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(...)));
    try {
        // Process each file and save it to file
    }
    finally {
        try {
            in.close();
        }
        catch (IOException ignored) {}
        try {
            out.close();
        }
        catch (IOException ignored) {}
    }
}
  

Обратите внимание, что IOException ы, которые могут быть выданы при закрытии потоков, должны игнорироваться, иначе вы потеряете потенциальное исходное исключение.

Другая проблема заключается в том, что оба потока находятся в одном файле, что не работает. Итак, я полагаю, вы используете два разных файла.

Комментарии:

1. Я пытаюсь это сделать и возвращаюсь к вам с результатом

2. Я предлагаю придерживаться одного try finally для каждого базового ресурса. Если new BufferedOutputStream(new FileOutputStream(new File(...))) генерируется исключение, вы получаете беспорядок. Если закрытие выходного потока, скажем, вызывает исключение, вы просто пошли и создали поврежденный файл и проигнорировали его. Возможно, есть другая ошибка, но если вы делаете это неумным способом, все просто работает, и вам не нужно думать об этом.

3. только что попробовал, и результат в два раза быстрее, чем в предыдущей версии, и он не займет места.

Ответ №2:

Close() может занимать до 20 мс. Я сомневаюсь, что это ваша программа, если у вас нет 1000 файлов.

Я подозреваю, что ваша проблема с производительностью заключается в отсутствии буферизации ввода и вывода. Можете ли вы также показать свои буферные оболочки?

Комментарии:

1. outputfile имеет размер около 200 МБ, поэтому он закрывает файл размером 200 мб в каждом цикле, вызывает ли это замедление?

2. close () закрывает flush (), поэтому сброс на диск (до) 100 МБ замедлит его, да.

3. Если у вас есть диск, на который вы выполняете чтение / запись, вы должны ожидать, что скорость чтения / записи на нем составит около 30 МБ в секунду. Если вы читаете и записываете 200 МБ, это должно занять около 13 секунд. 200*2/30. Это сколько времени это занимает?

4. Это съело весь мой / temp в c: , в любом случае, я думаю, что buffer решил проблему

Ответ №3:

вы, конечно, можете создать очередь выходных потоков и передать ее фоновому потоку, который обрабатывает закрытие этих выходных потоков. То же самое для входных потоков. В качестве альтернативы вы можете оставить это на усмотрение JVM — просто не закрывайте файлы и предоставьте GC делать это, когда объекты будут завершены.

Комментарии:

1. то есть вы имеете в виду, что мне не нужно закрывать () ?

2. речь не о «должен» — поскольку все зависит от контекста. Я лично не оставил бы close() в jvm, однако вы могли бы это сделать.

3. Если вы попытаетесь разделить потоки, вы можете фактически снизить производительность при вводе-выводе. Особенно, если это происходит при запуске этих старых электромеханических устройств с вращающимися носителями. (Хотя вы получаете буферизацию, подумайте о бедных маленьких головах, мечущихся вокруг, как будто они потеряли своих цыплят.)