2012-02-28 33 views
11

Tôi có một giao diện định nghĩa là:Bạn có thể chuyển luồng qua nhiều phương thức không?

public interface IClientFileImporter 
{ 
    bool CanImport(Stream stream); 
    int Import(Stream stream); 
} 

Ý tưởng là thực hiện bất kỳ dòng tập tin và chạy nó thông qua một loạt các hiện thực của giao diện này để xác định cái nào nên xử lý các tập tin. Một số việc triển khai có thể tìm kiếm một hàng tiêu đề nhất định, trong khi những người khác có thể tìm kiếm một chuỗi byte nhất định, v.v ...

Câu hỏi của tôi là, tôi có thể bỏ qua một luồng như thế này miễn là tôi không bao giờ đóng nó? Mỗi phương pháp sẽ phải chịu trách nhiệm đặt lại luồng vào vị trí 0 nếu cần thiết, nhưng có bất kỳ vấn đề tiềm ẩn nào khác (ngoài an toàn luồng) không? Mã này thực sự có mùi, IMO, nhưng tôi không chắc chắn về cách tốt hơn để làm điều đó.

+0

Tôi không nghĩ đó là một khái niệm tồi ngay từ đầu. Bạn không biết những gì triển khai sẽ cần từ luồng để cung cấp toàn bộ luồng có ý nghĩa. Để đảm bảo rằng việc triển khai không gây rối với luồng, bạn có thể triển khai một số loại trình bao bọc xung quanh Luồng (bắt nguồn từ chính luồng) ngăn chặn bất kỳ phương thức nào sửa đổi luồng cơ bản hoặc bất kỳ thứ gì bạn cần. Ngoài ra, tôi sẽ không yêu cầu thực hiện để thiết lập lại vị trí dòng. Người gọi của CanImport/Import có thể làm điều đó. Kết hợp điều này đảm bảo rằng không có importortr có thể gây hại cho luồng cơ bản. –

Trả lời

3

Để ngăn chặn luồng cơ bản bị sửa đổi, tạo luồng trình bao xuất phát từ Luồng và chỉ chuyển tiếp cuộc gọi an toàn tới luồng được bao bọc. Ngoài ra, không giả sử các phương thức Import/CanImport đặt lại vị trí dòng. Người gọi phương thức đó nên đặt lại luồng thành trạng thái hợp lệ trước khi chuyển nó sang Nhập/CanImport.

+0

Trong trình bao bọc luồng chỉ đọc này, bạn có thể ghi đè phương thức Vứt bỏ để tự động tua lại luồng nhưng không đóng nó không? – Chris

+0

Có, điều đó chắc chắn có thể hoạt động, theo cách đó bạn có thể sử dụng một khối sử dụng thuận tiện xung quanh các cuộc gọi đến CanImport/Import –

2

Nếu mỗi hàm trả về luồng giống như cách nó nhận được, tôi không nghĩ có vấn đề với nó.

+0

Tại sao phương pháp không sửa đổi luồng? Tôi nghĩ đọc và viết từ luồng là lý do bạn sẽ vượt qua nó. – cadrell0

+0

Nếu nó thay đổi luồng, bạn có thể nhận được tất cả các loại phụ thuộc giữa các hàm. Nó có thể được chấp nhận, nhưng OP đã nói về việc tua lại luồng mỗi lần. – zmbq

2

Đây không phải là vấn đề.

Mặc dù tôi có lẽ sẽ cơ cấu lại nó một chút:

public interface IClientFileImporter 
{ 
    int Import(Stream stream); 
} 

Sau đó, tôi sẽ có phương pháp nhập khẩu trả về một -1 nếu nó đã không thể. Có thể làm cho mã khác của bạn đơn giản hơn một chút.

+0

Tôi đồng ý với Chris, câu trả lời hay của Chris. Tôi nghĩ rằng điều này sẽ làm cho nó dễ dàng hơn một chút –

0

Bạn hoàn toàn có thể chuyển cùng một luồng sang nhiều phương pháp.

Cẩn thận với các luồng không thể tìm kiếm - có các luồng mà bạn không thể đặt lại vị trí. Lời bình luận của Andre Loker có lời khuyên tốt để kết nối Stream để các phương thức CanImport không làm xáo trộn luồng thực tế.

Bạn cũng có thể xem xét cung cấp rõ ràng một số phần "tiêu đề" của luồng cho phương pháp CanImport, cũng sẽ làm cho chúng ít linh hoạt hơn.

0

Nếu bạn lo lắng về việc truyền tải luồng vì bạn có thể chạy mã bên ngoài có thể không đáng tin cậy, thì tốt nhất bạn có thể làm là tạo luồng mới, chỉ đọc và truyền xung quanh để không có mã bên ngoài nào thay đổi nội dung của tệp cho đến khi bạn chắc chắn bạn muốn cho phép chúng.

public class ReadonlyStream : Stream 
{ 
    public ReadonlyStream(Stream baseStream) 
    { 
     ownerStream = baseStream; 
    } 

    private Stream ownerStream; 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override int Write(byte[] bits, int offset, int count) 
    { 
     throw new InvalidOperationException(); 
    } 

    // Other code ommitted 
} 
Các vấn đề liên quan