2011-01-03 8 views
8

Czytam kod kogoś innego. Oto sedno tego.FileOutputStream vs ByteArrayOutputStream

Klasa kompresuje i dekompresuje pliki za pomocą GZIPInputStream i GZIPOutputStream.

Oto fragment informacji o tym, co dzieje się podczas kompresji. Są to instancje klasy File.

FileInputStream fis = new FileInputStream(inputFile); 
GZIPOutputStream gzos = new GZIPOutputStream(new FileOutputStream(outputFile)); 

//the following function copies an input stream to an output stream 
IOUtils.copy(fis,gzos); 

//outputFile is the compressed file 
... 

Oto, co dzieje się podczas dekompresji.

GZIPInputStream gzis = new GZIPInputStream(new FileInputStream(inputFile)); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

//copies input stream to output stream 
IOUtils.copy(gzis,baos); 

//this method does as its name suggests 
FileUtils.writeByteArrayToFile(outputFile, baos.toByteArray()); 

//outputFile is the decompressed file 
... 

Co to możliwa przyczyna oryginalny programista wybrał FileOutputStream podczas kompresji i dekompresji podczas ByteArrayOutputStream? To mnie dezorientuje.

Jeśli nie ma dobrego powodu, myślę, że zmieniam je tak, aby były konsekwentne, aby uniknąć przyszłego zamieszania. Czy to dobry pomysł?

+0

Czy IOUtils i FileUtils są odpowiednie lub z biblioteki typu commons-io? – sblundy

+0

@blundy, są z bibliotek podobnych do commons-io. – Russell

Odpowiedz

11

Heh, wygląda na to, że skopiowali i wkleili kod z różnych źródeł? :-P Nie, poważnie, chyba że musisz sprawdzić zdekompresowane dane, możesz po prostu użyć BufferedOutputStream zarówno do kompresji, jak i dekompresji.

+0

To brzmi prawdopodobnie – sblundy

+1

W takim przypadku, poleciłbym moje użycie 'new BufferedOutputStream (new FileOutputStream (outputFile)' zamiast 'new FileOutputStream (outputFile)'? Czy wystąpiłby wzrost wydajności? – Russell

+1

Byłbym, prawdopodobnie to się pojawiło w celu poprawienia wydajności, gdy prawdziwym rozwiązaniem było użycie BufferedInputStream i BufferedOutputStream.) –

0

ByteArrayOutputStream dałoby mu/jej ładny OutOfMemoryError?

Poważnie, prawdopodobnie zostały wykonane w różnym czasie. Jeśli możesz, skonsultuję się z dziennikami VCS.

+0

Dobry pomysł. Będę musiał sprawdzić dzienniki. – Russell

4

Jest to więcej pamięci, ponieważ przechowuje całą zawartość w pamięci Java (w smaku byte[]). FileOutputStream zapisuje bezpośrednio na dysk i tym samym zmniejsza ilość pamięci. W tym konkretnym przypadku nie widzę żadnego rozsądnego powodu, aby użyć ByteArrayOutputStream. Nie modyfikuje później poszczególnych bajtów. Zostaje zapisany w niezmienionej formie do pliku. Jest to niepotrzebny krok pośredni.

2

Programator używał FileInputStream podczas kompresji i używał bufora podczas dekompresji. Myślę, że powodem było to, że jeśli nie udaje ci się dublować czytania pliku, nic złego się nie dzieje. Po prostu zawiedziesz i zostanie zgłoszony wyjątek.

Jeśli podczas dekompresji wystąpi błąd, a już rozpoczęto zapisywanie do pliku, plik jest uszkodzony. Postanowił więc najpierw napisać bufor, a następnie po zakończeniu dekompresji zapisać bufor na dysku. To rozwiązanie jest OK, jeśli masz do czynienia z relatywnie małymi plikami. W przeciwnym razie wymaga to dużej ilości pamięci i może spowodować OutOfMemeoryError.

Wyodrębnię zip bezpośrednio do pliku tymczasowy, a następnie zmień nazwę pliku tymczasowego na jego stałą nazwę. W końcu blok powinien usunąć plik tymczasowy.

+0

Dobre myślenie. Wydawało się, że w kodzie nie ma miejsca, by zajmować się nieudanymi zapisami, więc w tym konkretnym przypadku jest to pasta do kopiowania lub napisana w różnym czasie. – Russell