locked
I am using PCLStorage - where are the files going to? RRS feed

  • Question

  • User206855 posted

    Visual Studio 2015, Xamarin forms, PCL project, using PCLStorage. I am new to this stuff. Am I reading this wrong, in that I think that I only need to have the code in the Portable project, or do I need something in each separate project (IOS, Android, etc)? Here is the code (which I have tried in debug and release)...

    //https://github.com/dsplaisted/PCLStorage //http://www.nudoq.org/#!/Packages/PCLStorage/PCLStorage/FileSystemFolder/M/CreateFolderAsync IFolder rootFolder = FileSystem.Current.LocalStorage;

         try
         {
             string context = "this is a test file";
             string filename = "lou.txt";
             IFile file = await rootFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
             await file.WriteAllTextAsync(context);
             System.Diagnostics.Debug.WriteLine("LocalStorage: (" + rootFolder.Path + ")");
             System.Diagnostics.Debug.WriteLine("Saved: (" + file.Path + ")"); 
         }
         catch (Exception ex)
         {
             await DisplayAlert("Error message: ", ex.Message, "OK"); 
         }
         await DisplayAlert("Noerrors: ", "Is  file there?", "OK");
    
         ExistenceCheckResult exist = await rootFolder.CheckExistsAsync("lou.txt");
         if (exist == ExistenceCheckResult.FileExists)
         {
             await DisplayAlert("File Exists?", "Yes, file does exist", "OK"); 
         }
         else
             await DisplayAlert("File Exists?", "No, file does NOT exist", "OK");
    

    Whether I execute this on the Android Droid emulator, or on my actual Galaxy edge phone, it runs, but I can never find the files afterwards. the System.Diagnostics.debug.writelines, show this )...

    [0:] LocalStorage: (/data/user/0/SurveyCheck.Droid/files) [0:] Saved : (/data/user/0/SurveyCheck.Droid/files/lou.txt)

    I do not get to the exception error message, I do get to the 'noerrors' message. On the existancecheck, I get the "yes, file does exist' message.

    Now, I try to equate the /data/users/0/..." from the above two lines, to what is on my Edge, I go to settings\storage, and it shows Internal storage of 14.13 gb of 32.00 gb, and portable storage (just bought), of 5.50 mb used of 119 GB. So, I am not out of storage. Never having done this before, are I correct in assuming that it should be writing to the internal storage? If I select Internal Storage\Explore, in the list of folders shown, I do not see anything that looks like it relates to where I should be writing to (no '/Data/user/o'). So, I am assuming that the Android folder is where I should be looking (?). The Android has a Data folder, which I select, and it does have a SurveyCheck.Droid folder, and under that is a files folder, and under that is a ".override" folder, and under that is all the files related to the actual app. The lou.txt file is nowhere to be found.

    Is the "/data/user/o..." folders hidden somewhere? Please help me to understand.

    Friday, January 27, 2017 10:48 PM

All replies

  • User206855 posted

    Got up this morning and tried something different. I commented out the file creation, and modified the ExistanceCheckResult code, to see if the file (that I cannot physically find in storage), actually is there...

    ExistenceCheckResult exist = await rootFolder.CheckExistsAsync("lou.txt"); if (exist == ExistenceCheckResult.FileExists) { await DisplayAlert("File Exists? : ", "Yes, file does exist", "OK");

                IFile file2 = await rootFolder.GetFileAsync("lou.txt");
                string text = await file2.ReadAllTextAsync();
                await DisplayAlert("file contents: ", "'" + text + "' at : '" + file2.Path + "'", "OK");
    
            }
            else
                await DisplayAlert("File Exists?", "No, file does NOT exist", "OK");
    

    As you can see from the attached FileFound.png file, the file that I created yesterday, is there. I still cannot see it when I try to find it in storage. WHERE THE HECK IS IT?????? I need to identify where the file is, so that if need be, it can be retrieved outside of my app.

    If anyone knows, can you at least point me to where I can get the information that will point me in the right direction. Thanks.


    Saturday, January 28, 2017 12:25 PM
  • User206855 posted

    I have had no success to date in identifying where the folders and files that I create, are stored. It is somewhere in Internal storage.

    I tried attaching the files to an email using MessagingPlugin.EmailMessenger, and while I could see that the file was attached to the email (I saw the attachment when hitting the 'Send' button in the email), when I actually received the email , the attachment was not there. This posting...http://stackoverflow.com/questions/6058245/email-attachment-not-successful-in-android, says "there is no way to send attached file via email from internal storage. " This posting... https://github.com/cjlotz/Xamarin.Plugins/issues/49, in regard to attachments says "Its a result of Android M changes and the attachments need to use the FileProvider class for sending them. ", (but that might be specific to Android).

    It appears that PCLStorage only works with Internal storage, and cannot access the SD card (External storage). The problem with writing to external, is that not every user will have an external card. I will be looking at something like...https://developer.xamarin.com/guides/xamarin-forms/working-with/files/ (Saving and Loading files).

    Unless someone can either point out my mistakes, or point me to something else.

    Sunday, January 29, 2017 4:33 PM
  • User206855 posted

    Ok, for the time being I switched to using system.IO (only doing Android so far). Whether I do a text file, or an image file (after setting the access for the external storage in the manifest)...

    public void SaveText(string filename, string text)
        {
            var externalPath = Android.OS.Environment.ExternalStorageDirectory;
            var filePath = System.IO.Path.Combine(externalPath.ToString(), filename);
            System.IO.File.WriteAllText(filePath, text);
            MyGlobals.externalPath = filePath;
        }
        public void SaveImage(SkiaSharp.SKData skdata, string filename)
        {
            var externalPath = Android.OS.Environment.ExternalStorageDirectory.ToString();
            var filePath = System.IO.Path.Combine(externalPath.ToString(), filename);
            var fStream = new FileStream(filePath, FileMode.OpenOrCreate);
            skdata.SaveTo(fStream);
            MyGlobals.externalPath = filePath;
        }
    

    I can now see the files created above, in settings/storage/Internal Storage/explore. They are listed at the bottom (after the list of main storage folders). I should perhaps next try to create a folder there for the app files). I do find it confusing that I set the access for External, and reference the 'ExternalStoragedirectory' above, and yet the files are listed in Internal Storage. I am going to assume here that 'External', means external from the files that actually comprise the app itself. I have no idea of how to get to write to the SD card (which is listed under Storage/Portable storage), nor am I sure that this is appropriate to do.

    Now, when I send an email, not only do I see the attachment on the email, but the other end actually does receive the attachment.

    It has been a long weekend.

    Sunday, January 29, 2017 9:29 PM
  • User1669 posted

    If I select Internal Storage\Explore, in the list of folders shown, I do not see anything that looks like it relates to where I should be writing to (no '/Data/user/o'). So, I am assuming that the Android folder is where I should be looking (?). The Android has a Data folder, which I select, and it does have a SurveyCheck.Droid folder, and under that is a files folder, and under that is a ".override" folder, and under that is all the files related to the actual app. The lou.txt file is nowhere to be found.

    This has to do with Android's security model. If you look at the source code for PCL Storage:

    https://github.com/dsplaisted/PCLStorage/blob/master/src/PCLStorage.FileSystem.Desktop/DesktopFileSystem.cs#L26

    You'll see that the it's writing to Environment.SpecialFolder.MyDocuments, which is going to write it somewhere that looks like: "/data/user/0/com.mycompany.myapp/files"

    The may be different, depending on the device. These files are considered "private files", meaning they can only be accessed by your application. They are sandboxed so no other application can access them. This includes File Managers. So if you're using an external File Manager to view these files, the File Manager will not have access to these folders/files. If you try to use a Terminal to access the files, you'll get some sort of Access Denied message. File Managers get the same error message, but suppress the error message so you don't get a million error messages when viewing folders/files.

    So to answer your question, the folders/files do exist, but your File Manager does not have access to view them. The only way for your File Manager to view private files is to root your phone. Probably not an option since rooting your phone will wipe your data. However, you can use DDMS and view the file system on an Emulator. Run your app on an emulator, and then use DDMS to view the file system. You should see your files there, keep track of the file path as it may vary.

    Monday, January 30, 2017 8:26 PM
  • User253120 posted

    @rmacias @louwho did you guys manage to get the PCL Storage working? I need to save image retrieved from my web service, currently developing on Android app only. But, probably it will be extended for iOS and Windows phone, so if there is a solution for this issue, I am planning to use this.

    Thursday, March 9, 2017 6:29 AM
  • User1669 posted

    What issue are you referring to? I'm using it and it works as expected. If you're trying to browse for the file using a File Manager you're not going to find it because of the Android security model I explained in my previous post. But the files are there, but the File Manager apps don't have access to view them unless your device is rooted.

    Thursday, March 9, 2017 4:18 PM
  • User206855 posted

    I need to see my files, be able to copy them, delete them, etc., and to let the users do the same. So, I am not using PCL, instead I am using Interface \ Dependency.

    In the PCL project, IWorkWithFiles.cs...

    using System.Collections.ObjectModel;

    namespace Test1 { public interface IWorkWithFiles { void SaveViewList(ObservableCollection linesListView ); }

    }

    In the PCL \ mainpage...

    "DependencyService.Get().SaveViewList(MyGlobals.collectionHolder.LinesList);"

    In the Android project... WorkWithFilesAndroid.cs...

    using Xamarin.Forms; using System.IO; using System.Collections.ObjectModel; using static Android.Provider.Settings; using Android.OS;

    [assembly: Dependency(typeof(Test1.Droid.WorkWithFilesAndroid))]

    namespace Test1.Droid { public class WorkWithFilesAndroid : IWorkWithFiles {

       public void SaveViewList(ObservableCollection<LinesModel> linesListView)
        {
            var filePath = "";
    
            //create dir if it does not exist
            var documentsPath = Android.OS.Environment.ExternalStorageDirectory.ToString();
            var dirName = System.IO.Path.Combine(documentsPath.ToString(), "Test1");
            Directory.CreateDirectory(dirName);
    
            //Storage\Explore could not open .XML file, thus using .txt for extension
    
                filePath = System.IO.Path.Combine(dirName, "TempLines.txt");
                TextWriter tw = new StreamWriter(filePath);
    
                foreach (var line in linesListView)
                {
                    tw.WriteLine("test info");
                }
                tw.WriteLine("<\\LinesModels>");
                tw.Close();            
    

    }

    On my S7 Edge, I can then go to Settings/Storage/Internal Storage/Explore/Test1, and see my files.

    Friday, March 10, 2017 12:10 AM
  • User328763 posted

    @louwho said: Ok, for the time being I switched to using system.IO (only doing Android so far). Whether I do a text file, or an image file (after setting the access for the external storage in the manifest)...

    public void SaveText(string filename, string text) { var externalPath = Android.OS.Environment.ExternalStorageDirectory; var filePath = System.IO.Path.Combine(externalPath.ToString(), filename); System.IO.File.WriteAllText(filePath, text); MyGlobals.externalPath = filePath; } public void SaveImage(SkiaSharp.SKData skdata, string filename) { var externalPath = Android.OS.Environment.ExternalStorageDirectory.ToString(); var filePath = System.IO.Path.Combine(externalPath.ToString(), filename); var fStream = new FileStream(filePath, FileMode.OpenOrCreate); skdata.SaveTo(fStream); MyGlobals.externalPath = filePath; }

    This worked great for me too, thanks

    Monday, June 19, 2017 8:10 AM