2010-06-15 25 views
5

Tôi đã sử dụng std::istreamostream như một giao diện đa hình cho truy cập ngẫu nhiên nhị phân I/O trong C++, nhưng có vẻ như tối ưu trong nhiều cách:khuyến nghị cho một C++ đa hình, seekable, nhị phân I/O giao diện

  • Tìm kiếm 64 bit không có khả năng di chuyển và dễ bị lỗi do giới hạn streampos/streamoff; hiện đang sử dụng boost/iostreams/positioning.hpp như một cách giải quyết, nhưng nó đòi hỏi sự thận trọng
  • hoạt động Thiếu như cắt bỏ hoặc mở rộng một tập tin (ala POSIX ftruncate)
  • Sự mâu thuẫn giữa việc triển khai cụ thể; ví dụ. stringstream có các vị trí nhận/đặt độc lập trong khi filestream không
  • Sự không thống nhất giữa các triển khai nền tảng; ví dụ. hành vi của tìm kiếm thông qua vào cuối của một tập tin hoặc sử dụng failbit/badbit về lỗi
  • Đừng cần tất cả các cơ sở định dạng của stream hoặc thậm chí có thể đệm của streambuf
  • streambuf báo cáo lỗi (tức là trường hợp ngoại lệ so với trả lại một chỉ số lỗi) được cho là implementation-dependent trong thực tế

tôi thích giao diện đơn giản được cung cấp bởi các Boost.Iostreams Device concept, nhưng nó cung cấp như chức năng mẫu chứ không phải là một lớp đa hình. (Có một device class, nhưng nó không đa hình và chỉ là một lớp trợ giúp thực hiện không nhất thiết được sử dụng bởi việc triển khai thiết bị được cung cấp.) Tôi chủ yếu sử dụng các tệp đĩa lớn, nhưng tôi thực sự muốn đa hình để tôi có thể dễ dàng thay thế các triển khai thay thế (ví dụ sử dụng stringstream thay vì fstream để kiểm tra đơn vị) mà không có sự phức tạp và biên dịch thời gian biên dịch của việc tạo mẫu sâu.

Có ai có bất kỳ đề xuất nào về cách tiếp cận tiêu chuẩn cho điều này không? Nó có vẻ như là một tình huống phổ biến, vì vậy tôi không muốn phát minh ra giao diện của mình một cách không cần thiết. Ví dụ, một cái gì đó giống như java.nio.FileChannel có vẻ lý tưởng.

Giải pháp tốt nhất của tôi cho đến nay là đặt một lớp đa hình mỏng lên trên thiết bị Boost.Iostreams. Ví dụ:

class my_istream 
{ 
public: 
    virtual std::streampos seek(stream_offset off, std::ios_base::seekdir way) = 0; 
    virtual std::streamsize read(char* s, std::streamsize n) = 0; 
    virtual void close() = 0; 
}; 

template <class T> 
class boost_istream : public my_istream 
{ 
public: 
    boost_istream(const T& device) : m_device(device) 
    { 
    } 

    virtual std::streampos seek(stream_offset off, std::ios_base::seekdir way) 
    { 
     return boost::iostreams::seek(m_device, off, way); 
    } 

    virtual std::streamsize read(char* s, std::streamsize n) 
    { 
     return boost::iostreams::read(m_device, s, n); 
    } 

    virtual void close() 
    { 
     boost::iostreams::close(m_device); 
    } 

private: 
    T m_device; 
}; 

Trả lời

0

Tôi vừa kết thúc với một bộ giao diện trừu tượng tương tự như những gì tôi đã nêu trong câu hỏi. Dường như không có bất kỳ tiêu chuẩn nhẹ, đa hình nào cho việc này ...

1

Bạn có xem giao diện QIODevice và lớp con của Qt không? Tôi không hoàn toàn chắc chắn nếu nó phù hợp với nhu cầu của bạn, nhưng có lẽ giá trị của nó một thử: QIODevice.

+0

Cảm ơn con trỏ, tôi đã quên về Qt. Tôi không muốn phụ thuộc vào nó, nhưng nó cung cấp một số quan điểm. –

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