Подтвердить что ты не робот

Использование BufferedInputStream

Позвольте мне предисловие к этому сообщению с одной осторожностью. Я новичок, когда речь заходит о Java. Я некоторое время программировал PHP, но я был готов сделать настольное приложение, поэтому решил пойти с Java по разным причинам.

Приложение, над которым я работаю, находится на начальных этапах (менее 5 классов), и мне нужно прочитать байты из локального файла. Как правило, файлы в настоящее время составляют менее 512 КБ (но в будущем могут увеличиться). В настоящее время я использую FileInputStream для чтения файла в массивы с тремя байтами, что отлично удовлетворяет моим требованиям. Тем не менее, я видел упомянутый BufferedInputStream, и мне было интересно, подходит ли мне то, что я делаю сейчас, или если я должен использовать BufferedInputStream.

Я провел некоторое исследование и прочитал несколько вопросов здесь о переполнении стека, но у меня все еще возникают проблемы с пониманием лучшей ситуации, когда следует использовать и не использовать BufferedInputStream. В моей ситуации первый массив, в который я читаю байты, составляет всего несколько байтов (менее 20). Если данные, полученные мной, хороши в этих байтах, я читаю остальную часть файла еще на двух байтовых массивах разного размера.

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

Прошу прощения за такой длинный пост, но я действительно хочу узнать и понять лучший способ сделать это. У меня всегда есть плохая привычка, когда я догадываюсь о своих решениях, поэтому мне хотелось бы получить обратную связь. Спасибо!

4b9b3361

Ответ 1

Если вы последовательно делаете небольшие чтения, то BufferedInputStream даст вам значительно лучшую производительность. Каждый запрос на чтение в небуферизованном потоке обычно приводит к системному вызову операционной системы для считывания запрошенного количества байтов. Накладные расходы на выполнение системного вызова могут составлять тысячи машинных инструкций для каждой системы. Буферизованный поток уменьшает это, делая одно большое чтение для (скажем) до 8k байт во внутренний буфер и затем выдавая байты из этого буфера. Это может значительно сократить количество системных вызовов.

Однако, если вы последовательно делаете большие чтения (например, 8k или более), тогда BufferedInputStream замедляет работу. Обычно вы не уменьшаете количество системных вызовов, а буферизация вводит дополнительный шаг копирования данных.

В вашем прецеденте (где вы сначала читаете 20-байтовый кусок, а затем много больших кусков), я бы сказал, что использование BufferedInputStream скорее приведет к снижению производительности, чем к увеличению. Но в конечном счете это зависит от фактических шаблонов чтения.

Ответ 2

Если вы используете относительно большие массивы, чтобы читать данные за кусок за раз, то BufferedInputStream будет просто вводить расточительную копию. (Помните, read не обязательно читает весь массив - вы можете захотеть DataInputStream.readFully). Где BufferedInputStream выигрывает при создании большого количества небольших чтений.

Ответ 3

BufferedInputStream читает больше файла, который вам нужен заранее. Насколько я понимаю, он делает больше работы заранее, например: 1 большое непрерывное чтение диска и делает много в плотном цикле.

Что касается профилирования - мне нравится профилировщик, который встроен в netbeans. С этим очень легко начать.: -)

Ответ 4

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

Ответ 5

    import java.io.*;
    class BufferedInputStream
    {
            public static void main(String arg[])throws IOException
            {
                FileInputStream fin=new FileInputStream("abc.txt");
                BufferedInputStream bis=new BufferedInputStream(fin);
                int size=bis.available();
                while(true)
                {
                        int x=bis.read(fin);
                        if(x==-1)
                        {
                                bis.mark(size);
                                System.out.println((char)x);
                        }
                }
                        bis.reset();
                        while(true)
                        {
                                int x=bis.read();
                                if(x==-1)
                                {
                                    break;
                                    System.out.println((char)x);
                                }
                        }

            }

    }