2010-03-02 29 views
17

Có một vài phương pháp nhà máy trong Google Guava để tạo InputSuppliers, ví dụ: từ một byte[]:Có cách nào ngắn gọn để tạo InputSupplier cho InputStream trong Google ổi không?

ByteStreams.newInputStreamSupplier(bytes); 

Hoặc từ một File:

Files.newInputStreamSupplier(file); 

Có cách nào tương tự để tạo ra một InputSupplier cho một InputStream được?

Đó là, một cách mà Hơn nữa ngắn gọn hơn một lớp vô danh:

new InputSupplier<InputStream>() { 
    public InputStream getInput() throws IOException { 
     return inputStream; 
    } 
}; 

Bối cảnh: Tôi muốn sử dụng InputStreams với ví dụ Files.copy(...) hoặc ByteStreams.equal(...).

Trả lời

10

Không, tôi chưa thấy gì cả.
Tôi nghĩ bạn đã tìm ra cách tốt nhất.
Cách duy nhất để lưu trữ luồng đầu vào trong mảng byte hoặc tệp và tạo Nhà cung cấp với ByteStreams.newInputStreamSupplier() hoặc Files.newInputStreamSupplier(), nhưng tôi sẽ không khuyến khích làm như vậy.
Bạn cũng có thể sử dụng

public static long copy(InputStream from, OutputStream to)
từ
ByteStreams
see: src

+3

http://stackoverflow.com/a/19553971/9636 phải là câu trả lời đúng bởi vì nó giải thích lý do tại sao bạn không thể làm điều đó. –

+0

Bạn nói đúng, nhưng jbyler đã đề xuất giải pháp nào đó ba năm sau đó;) – elou

+0

Đó là giải pháp mà tôi liên kết đến. –

2

Đó sẽ là như sai như gói một Iterator để một Iterable, tôi cảm thấy có như zero xác suất của một điều như vậy đi vào thư viện. Như bạn nói, bạn có thể sử dụng phương thức ByteStreams.copy(), nhưng dường như không có lý do rõ ràng nào để làm bằng() trên hai luồng.

Tôi hiểu các tác giả ổi do dự để thêm một phương pháp (tầm thường) - mức độ phổ biến (hoặc một phần, nhưng không biết luồng đã được để lại ở đâu, vì vậy tốt nhất là không thể sử dụng sau đó) đọc hai luồng để xem chúng có giống nhau không, không có bất kỳ xử lý dữ liệu nào khác không? Những byte này đến từ một nguồn không đọc được, chẳng hạn như một ổ cắm mạng? Nếu không, nếu nó chỉ là một tập tin ở đâu đó, hoặc một mảng byte trong bộ nhớ, có những cách khác cho vay mình để làm một bài kiểm tra bình đẳng.

13

Không có cách nào để chuyển đổi một tùy InputStream thành một InputSupplier<InputStream>, bởi vì một InputSupplier<InputStream> được coi là một đối tượng mà có thể tạo ra một tươi, mới InputStream mỗi khi phương pháp getInput() của nó được gọi. Điều này chỉ có thể khi nguồn byte cơ bản có sẵn để tái sử dụng; do đó, các phương thức của nhà máy mất byte[] hoặc File và trả lại InputSupplier<InputStream>.

Như Dimitris gợi ý, InputSupplier liên quan đến InputStream giống như cách Iterable liên quan đến Iterator. Lớp ẩn danh bạn mô tả không chính xác vì nó trả về luồng cùng một luồng mỗi khi getInput() được gọi, vì vậy các lời gọi tiếp theo sẽ trả lại InputStream đã cạn và đóng.

Đây là một vấn đề khác với lớp ẩn danh của bạn: một phần của động lực cho InputSupplier là giới hạn mức hiển thị của InputStream thực tế để có thể tự động đóng. Nếu bạn quấn InputStream bên ngoài có thể nhìn thấy được trong một số InputSupplier và sau đó chuyển nó vào phương thức tiện ích, phương pháp tiện ích có thể đóng InputStream của bạn. Bạn có thể được OK với điều đó nhưng đó không phải là một mô hình sử dụng sạch sẽ mà Guava muốn quảng cáo.

Khi tôi thấy mình muốn làm điều tương tự, tôi nhận ra mình đang làm ngược lại. Thay vì làm điều này:

Files.copy(InputSupplier.of(inputStream), destinationFile); 

(không tồn tại), tôi nên thay vì được làm điều này:

ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(destinationFile)); 
+0

Câu trả lời này có thể được cập nhật để nó cập nhật hơn không? Theo thời gian của nhận xét này, tất cả các lớp nhà cung cấp hiện không được chấp nhận. – chakrit

+0

Xin lỗi @chakrit, nhưng tôi không còn sử dụng ổi và tôi không quen thuộc với những ẩn dụ hiện tại. Nếu ai đó viết lên một phiên bản mới với các lớp học mới, tôi sẽ rất vui khi bỏ phiếu cho nó! – jbyler

Các vấn đề liên quan