Переключение с ApplicationData.Текущий.LocalFolder-Knownfolders.DocumentsLibrary

В настоящее время я разрабатываю приложение для киоска посетителей для gravesite, где одна из функций извлекает данные из файла csv и использует эти данные для заполнения listview. Следующий код берет данные и возвращает их в могилу типа списка.

    public  class Grave 
    {
        public string plots { get; set; }
        public string DOBS { get; set; }
        public string lastNames { get; set; }
        public string firstNames { get; set; }
        public string companys { get; set; }
        public string regts { get; set; }
        public string unitTypes { get; set; }
        public string states { get; set; }
        public string ranks { get; set; }
        public string sections { get; set; }
        public string image { get; set; }
        public string text { get; set; }
        public string notenums { get; set; }
     }



public class GraveManager
{



    public  static  List<Grave> GetGrave() 
    {   //points to desired folder
        StorageFolder folder = ApplicationData.Current.LocalFolder;

        string csvPath = folder.Path + @"PGexcel.csv";
        //loads .csv file from folder
        Csv csv = new Csv();

        //property that tells csv parser to not treat the first row as data
        csv.HasColumnNames = true;

        bool success1;
        success1 = csv.LoadFile(csvPath);

        //name of columns
        string plot = "Plot", DOB = "Date_of_Death", lastName = "Last_Name", firstName = "First_Name", company = "Company", regt = "Regt", state = "State", unitType = "Unit_Type", Rank = "Rank", Section = "Section", Notables= "Notables";


        //initialize string of arrays for each column
        string[] OCplots = new string[csv.NumRows];
        string[] OCDOBS = new string[csv.NumRows];
        string[] OClastNames = new string[csv.NumRows];
        string[] OCfirstNames = new string[csv.NumRows];
        string[] OCcompanys = new string[csv.NumRows];
        string[] OCregts = new string[csv.NumRows];
        string[] OCunitTypes = new string[csv.NumRows];
        string[] OCstates = new string[csv.NumRows];
        string[] OCranks = new string[csv.NumRows];
        string[] OCsections = new string[csv.NumRows];
        string[] OCimage = new string[csv.NumRows];
        string[] OCtext = new string[csv.NumRows];
        string[] OCnotenums = new string[csv.NumRows];


        //populates the arrays with values from .csv file
        for (int i = 0; i < csv.NumRows; i++)
        {

            OCplots[i] = csv.GetCellByName(i, plot);
            OCDOBS[i] = csv.GetCellByName(i, DOB);
            OClastNames[i] = csv.GetCellByName(i, lastName);
            OCfirstNames[i] = csv.GetCellByName(i, firstName);
            OCcompanys[i] = csv.GetCellByName(i, company);
            OCregts[i] = csv.GetCellByName(i, regt);
            OCunitTypes[i] = csv.GetCellByName(i, unitType);
            OCranks[i] = csv.GetCellByName(i, Rank);
            OCsections[i] = csv.GetCellByName(i, Section);
            OCstates[i] = csv.GetCellByName(i, state);
            OCnotenums[i] = csv.GetCellByName(i, Notables); 
        }



        //concantenate arrays with .jpg .txt to call for corresponding files
        for (int i = 0; i < csv.NumRows; i++)
        {
            //OCimage[i] = "C:/Users/POGR_ADMIN/AppData/Local/Packages/6b3614f6-6a5f-48fc-9687-80291e70b64d_phwtyg9y34v1t/LocalState/" + OCplots[i] + ".jpg";
            OCimage[i] = folder.Path + @"" + OCplots[i] + ".jpg";
            OCtext[i] = folder.Path + @""+ OCplots[i] + ".txt";  
        }

        var graves = new List<Grave>();



        //attempt to populate List using the for loop
        for (int i = 0; i < csv.NumRows; i++)
        {
            graves.Add(new Grave { plots= OCplots[i], DOBS = OCDOBS[i], lastNames = OClastNames[i], firstNames = OCfirstNames[i], companys = OCcompanys[i], regts = OCregts[i], states = OCstates[i], unitTypes = OCunitTypes[i],ranks = OCranks[i], sections = OCsections[i], image = OCimage[i], text = OCtext[i], notenums = OCnotenums[i] });

        }




        return graves;             

    }
}

Затем я инициализирую могилу типа списка на другой странице и заполняю ее путем вызова метода при вызове конструктора. Который показан здесь:

   public List<Grave> Graves;

   public FindaGrave()
    {
        this.InitializeComponent();
        GraveInitializer();

    }

     public void GraveInitializer()
    {
        Graves = GraveManager.GetGrave();
    }

Этот код работает отлично и прекрасно и заполняет listview именно так, как я предполагал. Тем не менее, было доведено до моего внимания, что есть много ошибок в файле csv, которые они нашли и планируют найти из-за человеческой ошибки. С учетом сказанного, они хотят иметь возможность внести изменения в csv-файл, и изменения будут отображаться после перезагрузки приложения(без какой-либо помощи от меня). Из — за локальной папки состояния упаковывается единственный способ, который я счел нужным сделать это было бы изменить
StorageFolder folder = ApplicationData.Current.LocalFolder;в StorageFolder folder = KnownFolders.DocumentsLibrary;

Я чувствовал, что если я убедился, что файл находится в библиотеке документов, добавил возможность в манифесте пакета приложения как так <uap:Capability Name="documentsLibrary" />и добавить соответствующую ассоциацию типов файлов, что он должен работать так же. Тем не менее, когда я запускаю его, список больше не отображается, и после того, как я отладил немного, больше нет значения для folder.Pathи string csvPath просто становится равным ‘» PGexcel.csv». Я в полной растерянности, потому что то, что я думал, будет быстрым решением, закончилось чем-то очень трудным, кроме того, я новичок в UWP, так что это не помогает. Я искал дни и не могу найти решение и любая помощь по этому вопросу будет очень признателен. Вы будете спасателем жизни!!

2 ответа

  1. oke I проверил ваш код и проблема в том, что приложения UWP являются своего рода песочницей и имеют только полный доступ к ApplicationData. Даже если вам удастся получить полный путь за пределами данных приложения, вы не сможете просто открыть его. Их необходимо открыть с помощью класса KnownFolders или сохранить в классе StorageApplicationPermissions

    Лучше всего было бы использовать API Storiage, чтобы открыть filestream и передать его вашему парсеру csv, но я не уверен, что ваши Парсеры csv принимают поток

  2. Поскольку приложения UWP должны быть безопасными, им не разрешается напрямую обращаться к расположениям файловой системы данных, не относящимся к приложениям, с помощью путей.

    Вы все еще можете использовать StorageFileAPI, хотя, и это должно быть достаточно в вашем случае, если ваша библиотека CSV поддерживает ввод из строки, а не файла.

    public static async Task<List<Grave>> GetGraveAsync() 
    {   
        //points to desired folder
        StorageFolder folder = ApplicationData.Current.LocalFolder;
        //find the file
        StorageFile csvFile = await folder.GetFileAsync( "PGexcel.csv" );
    
    
        //loads .csv file from folder
        Csv csv = new Csv();
    
        //property that tells csv parser to not treat the first row as data
        csv.HasColumnNames = true;
    
        bool success1;
    
        //load the CSV data from string
        success1 = csv.LoadFromString( await FileIO.ReadAllText(csvFile) );
    
        //... rest of your code
    
        return graves;             
    }
    

    StorageApplicationPermissions.FutureAccessList

    Самым простым решением проблемы было бы позволить пользователям выбрать файл при первом запуске приложения с помощьюFileOpenPicker, а затем сохранить его с помощью StorageApplicationPermissions.FutureAccessListAPI. Этот API позволяет сохранить разрешение на доступ к 1000 элементам хранения, чтобы получить доступ к файлу, выбранному пользователем. даже при нескольких запусках приложения.