One day, I had the idea of porting my .NET code to other platforms with the main logic (all that does not apply to the UI) being transferred to a separate Portable Class Library (PCL) library.
In theory, everything sounds cool - you can work with PCL on almost all devices, and not only with the .NET Framework, but even with Mono! With this approach, large multiplatform prospects are opening up, for example, porting Windows Phone code to Android and iOS using Xamarin.
')
But having familiarized myself with PCL more closely, I came to the conclusion that such a library is essentially a truncated .NET that takes into account the limitations of each platform. That is, even with seemingly similar WP8 and W8, it is not possible to push everything into PCL.
PCL Capabilities Table on Multiple Platforms
At first glance, my code had to go without problems (target platforms: Windows .NET, Windows 8, Windows Phone), but the compiler cursed System.IO, namely StreamReader, which directly opened the file.
Recalling that Windows 8 and Windows Phone have completely different ways to work with files and are different among themselves:
WP uses IsolatedStorage to access the application files, and Windows 8, although it has access to public folders, does it through Windows.Storage (WP8 can now also through it, but to maintain WP7 support, this method is not recommended). Having used Google, it became clear to me that it was impossible to organize access to files on pure PCL, and tips like transferring Steam from an application or hard file inclusion in a DLL for my solution did not fit. The fact is that the program worked with a large external dictionary and saved the temporary results of the work in files. But then the PCLStorage library came across, promising any kind of work with filesystems via PCL.
PCLStorage provides three interfaces - IFIle, IDirectory, IFileSystem, all of them provide asynchronous read and write operations for files and directories.
Note: All further tests were conducted on the "classic" Windows.
Example of writing a file:
public async Task PCLCreateFile(string name, string content) { IFolder localStorage = FileSystem.Current.LocalStorage; IFolder contentFolder = await localStorage.CreateFolderAsync("Content", CreationCollisionOption.OpenIfExists); IFile file = await contentFolder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting); await file.WriteAllTextAsync(content); }
Example of reading the file:
public async Task<string> PCLReadFile(string name) { IFolder localStorage = FileSystem.Current.LocalStorage; IFolder contentFolder = await localStorage.GetFolderAsync("Content"); IFile file = await contentFolder.GetFileAsync(name); return await file.ReadAllTextAsync(); }
Everything looks and works perfectly. But ... how to get access to the file, which is located in the program directory?
IFileSystem returns two LocalStorage and RoamingStorage paths. The first points to the directory that is allocated for the program in the current system, the second to the public directory for data synchronization. In particular, in Windows LocalStorage pointed to (AppData \ Local), which was far from being the application directory and did not contain any files.
Unfortunately, the PCLStorage application directory could not indicate.
Of course, it was possible to create a special installer, but what about the Store apps? However, a solution appeared - copying files to LocalStorage from the application itself (or downloading from the network in the PCL itself (not verified). Well, the method ultimately came out simpler than the Stream transfer, plus the opportunity to work with temporary files in a limited portable library environment.
PS: At the end of the experiment, it turned out that the support for WP7 from the latest version was thrown out, which is why it was actually started (due to the separate use of IsolatedStorage on WP and Windows.Storage on Windows 8).