Can you please tell if it is possible to read a file in a portable library? Maybe I am doing something wrong, but such a class as File , FileStream is not available in the portable library, it is impossible to create an instance of the StreamReader class or TextReader using the constructor, which is passed the file path as a parameter. When I try to write such a code, I swear that I cannot convert from "string" to "System.IO.Stream" '.

using System.IO; namespace Project { class Class1 { public Class1(string path) { StreamReader reader = new StreamReader(path); } } } 
  • 2
    "... but such a class as File .. is not available in the portable library." - yes, you are doing something wrong. This is the maximum that can be said by reading your question. - Alexander Muksimov February
  • Comments are not intended for extended discussion; conversation moved to chat . - Qwertiy

3 answers 3

Most likely, among the list of platforms you have chosen, including Silverlight or something like that. Silverlight is a browser plugin and is denied access to local files; because there are no classes you need.

In this form, the problem has no solution; You need to choose one of two things: either file access, or exotic platforms.

  • As you correctly pointed out, it is the Portable Class Library that is used. But not for Silverlight, but for iOS and Android. I thought then to try to write an application on android using this library, so as not to rewrite the code twice. Do I understand correctly that in this case the best way out is to use as a parameter not a string with an address to a file, but directly to StreamReader , and simply open the file in the final code and transfer the received stream to the constructor? - Oleg Klezovich
  • @OlegKlezovich apparently, yes. Accept TextReader or Stream This is on condition that you can open a file there at all. - Pavel Mayorov
  • under Android never wrote a program. There may be problems with opening the file? - Oleg Klezovich
  • @OlegKlezovich if there really isn’t System.IO.File, then yes, it can ... - Pavel Mayorov February
  • Under UWP there is, for example, StorageFile, which cannot be constructed along an arbitrary path. - VladD

Create a console application

 using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ClassLibrary1; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Class1 cl = new Class1("d://test.txt"); } } } 

We add a new project to Visual Studio using the tools of VisualStudio - a separate class Class1 in the form of a dll.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace ClassLibrary1 { public class Class1 { public Class1(string path) { StreamReader reader = new StreamReader(path); string str = reader.ReadLine(); } } } 

In the project manager on the console project, in the References section, add a link to the Class1 project.

We compile the solution, run it in the debugger - everything works

  • one
    error CS1503: Argument 1: cannot convert from 'string' to 'System.IO.Stream' - Pavel Mayorov
  • @Pavel Mayorov, before publishing the answer, I always check its performance. In my environment, Ms VisualStudio 2012 FrameWork 4, everything works - Alexander Muksimov
  • one
    And you have not forgotten that the author of the Portable Class Library, and not FrameWork 4? - Pavel Mayorov
  • @Pavel Mayorov, it says "... in a portable library ...", which can be interpreted as the author’s desire to create a separate portable dll. There are no words "Portable Class Library" :) - Alexander Muksimov
  • Learn English (and the official localization of Visual Studio nadmozgami). Portable Class Library in Russian is called precisely as "portable library". - Pavel Mayorov

You will need to add an interface to the PLC project.

Interface example:

 public interface IFileWorker { Task<bool> ExistsAsync(string filename); // проверка существования файла Task SaveTextAsync(string filename, string text); // сохранение текста в файл Task<string> LoadTextAsync(string filename); // загрузка текста из файла Task<IEnumerable<string>> GetFilesAsync(); // получение файлов из определнного каталога Task DeleteAsync(string filename); // удаление файла } 

Then for each of the projects (Android, iOS, etc.) to implement this interface.

An example implementation for Andriod:

 using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Xamarin.Forms; using System.Linq; [assembly: Dependency(typeof(FileApp.Droid.FileWorker))] namespace FileApp.Droid { public class FileWorker : IFileWorker { public Task DeleteAsync(string filename) { // удаляем файл File.Delete(GetFilePath(filename)); return Task.FromResult(true); } public Task<bool> ExistsAsync(string filename) { // получаем путь к файлу string filepath = GetFilePath(filename); // существует ли файл bool exists = File.Exists(filepath); return Task<bool>.FromResult(exists); } public Task<IEnumerable<string>> GetFilesAsync() { // получаем все все файлы из папки IEnumerable<string> filenames = from filepath in Directory.EnumerateFiles(GetDocsPath()) select Path.GetFileName(filepath); return Task<IEnumerable<string>>.FromResult(filenames); } public async Task<string> LoadTextAsync(string filename) { string filepath = GetFilePath(filename); using (StreamReader reader = File.OpenText(filepath)) { return await reader.ReadToEndAsync(); } } public async Task SaveTextAsync(string filename, string text) { string filepath = GetFilePath(filename); using (StreamWriter writer = File.CreateText(filepath)) { await writer.WriteAsync(text); } } // вспомогательный метод для построения пути к файлу string GetFilePath(string filename) { return Path.Combine(GetDocsPath(), filename); } // получаем путь к папке MyDocuments string GetDocsPath() { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); } } } 

For iOS project:

 using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Xamarin.Forms; using System.Linq; [assembly: Dependency(typeof(FileApp.iOS.FileWorker))] namespace FileApp.iOS { public class FileWorker : IFileWorker { public Task DeleteAsync(string filename) { File.Delete(GetFilePath(filename)); return Task.FromResult(true); } public Task<bool> ExistsAsync(string filename) { string filepath = GetFilePath(filename); bool exists = File.Exists(filepath); return Task<bool>.FromResult(exists); } public Task<IEnumerable<string>> GetFilesAsync() { IEnumerable<string> filenames = from filepath in Directory.EnumerateFiles(GetDocsPath()) select Path.GetFileName(filepath); return Task<IEnumerable<string>>.FromResult(filenames); } public async Task<string> LoadTextAsync(string filename) { string filepath = GetFilePath(filename); using (StreamReader reader = File.OpenText(filepath)) { return await reader.ReadToEndAsync(); } } public async Task SaveTextAsync(string filename, string text) { string filepath = GetFilePath(filename); using (StreamWriter writer = File.CreateText(filepath)) { await writer.WriteAsync(text); } } string GetFilePath(string filename) { return Path.Combine(GetDocsPath(), filename); } string GetDocsPath() { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); } } } 

To call the methods defined in the interface, use the DependencyService

For example, to read from a file, in the PLC project it is enough to add the following line of code:

  string Text = await DependencyService.Get<IFileWorker>().LoadTextAsync("Example.txt"); 

Material is taken from here.