Portable Library I/O Interface – Best Practices

cionet

I'm writing a new .NET portable library that can read a file format, and file I/O is not available for portable libraries. The article "How to Make Portable Class Libraries Work for You" states that I'll have to write platform-specific libraries to solve this for each platform. That's not a problem.

So, I'll have the file format reading code in the portable library, and then some platform-specific libraries to help with platform-specific I/O: one platform-specific library will be written using traditional traditional .NET System.IO.File, whereas the Windows Store apps-library will use Windows.Storage and the Windows Phone one will use System.IO.IsolatedStorage. I know WinRT is all asynchronous, but I only have experience with the traditional .NET File and synchronous I/O.

Each of these platform-specific libraries will reference the portable library and provide the file format reader with a platform-specific implementation of a data source object:

ISomeDataSource dataSource = new WinRTDataSource(@"filename.bin");
var reader = new FileFormatReader(dataSource);

How do I design the interface (e.g. the ISomeDataSource above) such that I can read and seek within the data? But then platform-agnostic and maybe even asynchronous?

I have access to all features of Visual Studio 2012 and C# 5 (async and await), but since I'm not on Windows 8 I cannot try WinRT.

Best Answer

I don't see anything hard about this, you can just create the interface (using asynchronous method for Read()) and then implement it three times:

interface ISomeDataSource
{
    Task<int> ReadAsync(byte[] buffer, int offset, int count);
    long Seek(long offset, SeekOrigin origin);
}

Both signatures are copied from Stream. Which is another option: use Stream instead of your interface. It has ReadAsync(), Seek() and more.

You can do this since System.IO and System.IO.IsolatedStorage directly use Stream (FileStream in System.IO and IsolatedStorageFileStream in System.IO.IsolatedStorage). WinRT has its own stream types, but you can convert those to Stream using extension methods from WindowsRuntimeStreamExtensions.