Что мне нужно сделать, чтобы этот код работал в Portable Class Library?

Мне интересно, является ли Portable Class Library еще более ограниченной по функциональности, чем Compact Framework.

Я пытаюсь портировать приложение CF/Windows CE (работает на портативном устройстве) на решение Xamarin, которое будет предназначаться для Android, iOS, Windows Phone и, возможно, других вещей.

Одна из проблем, с которыми я сталкиваюсь, заключается в том, что этот устаревший код (который работает под CF):

public static List<string> GetXMLFiles(string fileType, string startingDir)
{
    const string EXTENSION = ".XML";
    string dirName = startingDir;
    // call it like so: GetXMLFiles("ABC", "\\");  <= I think the double-whack is what I need for Windows CE device...am I right?
    var fileNames = new List<String>();
    try
    {
        foreach (string f in Directory.GetFiles(dirName))
        {
            string extension = Path.GetExtension(f);
            if (extension != null)
            {
                string ext = extension.ToUpper();
                string fileNameOnly = Path.GetFileNameWithoutExtension(f);
                if (fileNameOnly != null &&
                    ((ext.Equals(EXTENSION, StringComparison.OrdinalIgnoreCase)) &&
                     (fileNameOnly.Contains(fileType))))
                {
                    fileNames.Add(f);
                }
            }
        }
        foreach (string d in Directory.GetDirectories(dirName))
        {
            fileNames.AddRange(GetXMLFiles(fileType, d));
                // from Brad Rem's answer here: http://stackru.com/questions/22186198/why-is-this-function-returning-nothing-although-there-is-a-match/22186351?noredirect=1#22186351
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    return fileNames;
}

... не будет компилироваться в решении Xamarin/CPL. Я получаю: "Имя" Каталог "не существует в текущем контексте", и щелчок правой кнопкой мыши по этому слову не дает опции "решить".

Есть ли способ заставить PCL распознавать "Каталог" или я должен полностью переписать код? Если последнее, кто-нибудь есть какие-либо предложения о том, что делать / использовать вместо него?

Кроме того, есть ли URL, который покажет мне, что [недоступно] в PCL и / или на сайте, который покажет, сколько из предоставленного блока кода "PCL-ready"?

ОБНОВИТЬ

Первое изображение в этой статье очень яркое. Позже в нем конкретно говорится о том, что "Каталог" недоступен в сценарии PCL.

ОБНОВЛЕНИЕ 2

Я загрузил пакет PCLStorage, на который ссылается Дэниел Плейстед ниже, чтобы позволить мне получить доступ к файловой системе в рамках проекта PCL.

Используя пример кода в начале страницы загрузки [http://pclstorage.codeplex.com/] в качестве отправной точки, я получил это далеко:

public async Task<List<string>> GetXMLFiles(string fileType, string startingDir)
{
    const string EXTENSION = ".XML";

    IFolder rootFolder = FileSystem.Current.LocalStorage;
    IFolder folder = await rootFolder.GetFolderAsync(startingDir, CreationCollisionOption.OpenIfExists); //CreateFolderAsync(startingDir, CreationCollisionOption.OpenIfExists);
    List<string> fileNames = await folder.GetFilesAsync(EXTENSION);
    return fileNames;
}

... но "EXTENSION" в качестве аргумента для GetFilesAsync() неверен. Я получаю с этим, "Аргумент 1: не может преобразовать из" строки "в" System.Threading.CancellationToken ""

Итак, что мне нужно сделать, чтобы получить все файлы *.XML в папку?

ОБНОВЛЕНИЕ 3

Это компилируется, но я совсем не уверен, что это правильный способ, кроме того факта, что он просто получает все файлы из папки, а не только те, которые соответствуют "*.XML":

public async Task<List<IFile>> GetXMLFiles(string fileType, string startingDir)
{
    const string EXTENSION = ".XML";

    IFolder rootFolder = FileSystem.Current.LocalStorage;
    IFolder folder = await rootFolder.GetFolderAsync(startingDir, System.Threading.CancellationToken.None);
    IList<PCLStorage.IFile> fileNames = await folder.GetFilesAsync(System.Threading.CancellationToken.None);

    return fileNames.ToList();
}

4 ответа

Решение

Приложения Windows Phone не используют файловую систему операционной системы и ограничены использованием изолированного хранилища для сохранения и доступа к файлам, поэтому это пространство имен не предоставляет никаких дополнительных функций.

http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.io%28v=vs.105%29.aspx

Поскольку в PCL мне не удалось получить StreamWriter из строки (для этого требовался поток), я создал простой интерфейс для получения некоторых данных из реализации платформы. Вы также можете сделать это с DirectoryInfo и FileInfo.

https://github.com/sami1971/SimplyMobile/blob/master/Core/SimplyMobile.Text/IStreamLocator.cs

Реализация также очень проста, для WP8 нужен только один флаг компилятора:

https://github.com/sami1971/SimplyMobile/blob/master/WP8/SimplyMobile.Text.Platform/StreamLocator.cs

Рекурсивный поиск файлов *.XML:

    private static void PrintDirectory(IStreamLocator locator, string dir)
    {
        foreach (var file in locator.GetFileNames(dir, "*.XML"))
        {
            System.Diagnostics.Debug.WriteLine(file);
        }

        foreach (var di in locator.GetFolderNames(dir, "*"))
        {
            PrintDirectory(locator, di);
        }
    }

Другой вариант - использовать Shim, если он поддерживает все ваши платформы.

Покрытие API для файловых операций не является исчерпывающим, но оно проделывает долгий путь. В качестве бонуса он также дает вам доступ к куче других вещей.

Xamarin имеет сканер, который даст вам приблизительное представление о переносимости вашего кода: http://scan.xamarin.com/

Некоторые рекомендации о том, как работать с непереносимыми API-интерфейсами из PCL, см. В моем блоге: Как заставить переносимые библиотеки классов работать на вас

В частности, для файлового ввода-вывода вы можете попробовать мою библиотеку PCL Storage.

Другие вопросы по тегам