2013-07-08 22 views
7

Zawsze używałam FileWriter do pisania tekstu do pliku w Javie. Najwyraźniej możesz także użyć BufferedOutputStream. Po uważnym przeczytaniu obu javadocs, nie mogę powiedzieć, który był szybszy/bardziej wydajny.Wydajność: BufferedOutputStream vs FileWriter

Więc pytam: czy istnieje różnica wydajności (nawet jeśli minimalna) między tymi dwiema metodami wejścia/wyjścia pliku? Jeśli tak, jakie one są i dlaczego? Jeśli nie, dlaczego są one faktycznie takie same?

Czy istnieją scenariusze, w których preferowany jest jeden nad drugim? Z góry dziękuję!

Odpowiedz

9

Jeśli naprawdę chcesz porównać FileWriter z BufferedOutputStream napisać plik tekstowy, ten ostatni powinien być szybszy, ponieważ istnieje mniej operacji I/O.

  • W przypadku FileWriter każde wywołanie metody zapisu będzie trwało od razu (jest niebuforowane).
  • W przypadku BufferedOutputStream dane zostaną zapisane na dysku, jeśli bufor jest pełny (lub bufor jest przepłukiwany explicity przy użyciu metody flush).

Ale jeśli piszesz pliki tekstowe, należy użyć Writer; W tym przypadku możemy porównać FileWriter z BufferedWriter:

Patrząc na

FileWriter fw = new FileWriter(...) 

i

BufferedWriter bw = new BufferedWriter(new FileWriter(...) 

masz taką samą sytuację dotyczącą liczby operacji I/O.


A FileWriter wykorzystuje FileOutputStream wewnętrznie. Powodem użycia FileWriter jest to, że automatycznie używa domyślnego kodowania znaków podczas pisania do pliku (wewnętrzny ciąg Java jest zakodowany na przykład w UTF-8).Jeśli używasz OutputStream, trzeba kodować ręcznie w każdym zapisie:

Więc ten przykład dla BufferedWriter:

bw.write("Hello"); 

odpowiada tym przykładzie dla BufferedOutputStream:

bos.write("Hello".getBytes(Charset.forName("utf-8"))); 

jeśli domyślne kodowanie to utf-8.

An OutputStream dotyczy bajtów (surowych), natomiast Writer dotyczy znaków (tekstowych).

2

FileWriter pisze tekst do pliki, natomiast BufferedOutputStream posiada bufor dowolnych danych binarnych w pamięci przed zapisaniem go do innego strumienia binarnego, które trzeba dostarczyć. Nie robią tego samego, więc porównywanie ich wyników nie ma znaczenia.

Ogólnie buforowanie poprawia przepustowość aplikacji, ale zwiększa opóźnienie. W przypadku plików można wytworzyć większą wydajność na sekundę, ponieważ można przesłać większe bloki na dysk naraz, więc narzut na bajt jest niższy. Z drugiej strony, gdy dane są buforowane w pamięci, nie są zapisywane na dysku, więc uzyskanie określonego zapisu na dysku zajmuje dłuższy czas.

W przypadku FileWriter ma już wewnętrzny bufor, który pomaga w kodowaniu znaków w bajtach. Dodanie większej ilości buforowania prawdopodobnie ma niewielką wartość.

+0

Dzięki @Joni (+1) - ciekawa obserwacja, ale czy możesz * nie * zapisywać tekstu do plików z 'BufferedOutputStream'?!? [Ten artykuł] (http://www.javadb.com/write-to-file-using-bufferedoutputstream) wydaje się myśleć inaczej. Jeśli ten artykuł jest prawdziwy, to chociaż 'FileWriter' i' BufferedOutputStream' mogą być przeznaczone dla 2 różnych zastosowań, to * możliwe * (a tym samym punkt mojego pytania) jest porównanie ich wydajności podczas pisania tekstu do pliku. –

+0

Ponownie, bardzo interesujące rzeczy @Joni! Zgodnie z [to pytanie SO] (http://stackoverflow.com/questions/6108043/java-does-filewriter-use-a-buffer-it-acts-like-it-does-in-my-example) wydaje się możliwe zastąpienie wewnętrznego bufora używanego przez 'FileWriter'. Chciałbym to wypróbować, jeśli nie nic innego, dla mojej osobistej rozrywki. Dla mojego życia nie mogę wymyślić, jak skonfigurować 'OutputStreamWriter' i' FileOutputStream' i wprowadzić je do konstruktora 'FileWriter' - jakieś pomysły? I gdzie powinienem określić nowy rozmiar bufora? Jeszcze raz dziękuję za wspaniałą pomoc! –

+0

Jak widać w artykule, aby najpierw napisać tekst z 'BufferedOutputStream', konwertowali oni dowolny tekst na bajty ręcznie, przez caling' getBytes', co jest niewygodne i tworzy tablicę bajtów, która natychmiast staje się śmieciem – Joni