2011-01-03 1 views
8

Tôi đang đọc mã của người khác. Đây là ý chính của nó.FileOutputStream vs ByteArrayOutputStream

Một lớp nén và giải nén tệp bằng GZIPInputStream và GZIPOutputStream.

Đây là một đoạn trích về những gì diễn ra trong quá trình nén. inputFileoutputFile là các trường hợp của lớp 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 
... 

Bây giờ, đây là những gì đang xảy ra trong quá trình giải nén.

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 
... 

một lý do có thể lập trình viên ban đầu đã chọn FileOutputStream trong quá trình nén và giải nén ByteArrayOutputStream trong là gì? Nó làm tôi bối rối.

Trừ khi có lý do chính đáng, tôi nghĩ rằng tôi đang thay đổi chúng là nhất quán để tránh nhầm lẫn trong tương lai. Đây có phải là một ý tưởng tốt?

+0

IOUtils và FileUtils có phải là propritary hoặc từ lib như commons-io không? – sblundy

+0

@sblundy, chúng là từ libs như commons-io. – Russell

Trả lời

11

Heh, có vẻ như họ đã sao chép và dán mã từ các nguồn khác nhau? :-P Không, nghiêm túc, trừ khi bạn cần phải kiểm tra các dữ liệu giải nén, bạn chỉ có thể sử dụng một BufferedOutputStream cho cả nén và giải nén.

+0

Điều đó nghe có vẻ là – sblundy

+1

Trong trường hợp đó, bạn có đề nghị sử dụng 'BufferedOutputStream mới '(FileOutputStream mới (outputFile)' thay vì 'new FileOutputStream (outputFile)'? Sẽ có hiệu năng? – Russell

+1

Tôi có thể xuất hiện để cải thiện hiệu suất khi giải pháp thực sự là sử dụng BufferedInputStream và BufferedOutputStream –

0

ByteArrayOutputStream sẽ cho anh ấy/cô ấy một cái đẹp OutOfMemoryError?

Nghiêm túc, chúng có thể được thực hiện vào các thời điểm khác nhau. Nếu bạn có thể, tôi sẽ tham khảo nhật ký VCS.

+0

Ý tưởng hay. Tôi sẽ phải kiểm tra các bản ghi. – Russell

4

ByteArrayOutputStream là nhiều bộ nhớ hơn vì nó lưu trữ toàn bộ nội dung trong bộ nhớ của Java (theo hương vị của byte[]). Các FileOutputStream ghi vào đĩa trực tiếp và do đó ít hogging bộ nhớ. Tôi không thấy bất kỳ lý do hợp lý nào để sử dụng ByteArrayOutputStream trong trường hợp cụ thể này. Nó không phải là sửa đổi các byte cá nhân sau đó. Nó chỉ nhận được văn bản không thay đổi để tập tin sau đó. Đó là một bước trung gian không cần thiết.

2

Lập trình viên đã sử dụng FileInputStream trong khi nén và sử dụng bộ đệm khi giải nén. Tôi nghĩ rằng lý do là nếu bạn thất bại khi duinr đọc tập tin không có gì xấu xảy ra. Bạn chỉ thất bại và một ngoại lệ được ném ra.

Nếu bạn thất bại trong khi giải nén và bạn đã bắt đầu viết để tệp bị hỏng. Vì vậy, ông quyết định viết bộ đệm đầu tiên và sau đó khi giải nén được hoàn thành để ghi bộ đệm trên đĩa. Giải pháp này là OK nếu bạn đang đối phó với các tập tin tương đối nhỏ. Nếu không, điều này đòi hỏi nhiều bộ nhớ và có thể tạo ra OutOfMemeoryError.

Tôi muốn trích xuất zip trực tiếp thành tạm thời tệp và sau đó đổi tên tệp tạm thời thành tên vĩnh viễn của nó. Cuối cùng khối nên cẩn thận để xóa các tập tin tạm thời.

+0

Tư duy tốt. Dường như không có nơi nào trong mã để chăm sóc viết sai, vì vậy tôi đoán trong trường hợp cụ thể này, đó là dán bản sao hoặc được viết vào những thời điểm khác nhau. – Russell