2

For my program I have to include huge index and data files in the program bundle. Because it is an universal app, I have included these files in a folder named "Data" within the "Shared" Project.

Now I try to read:

StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("Data/"+fileName);
Stream stream = (await file.OpenReadAsync()).AsStreamForRead();
BinaryReader reader = new BinaryReader(stream);
Windows.Storage.FileProperties.BasicProperties x = await file.GetBasicPropertiesAsync();

I get a System.ArgumentException "mscorlib.ni.dll" at the first line. What's wrong?

If somebody can help me and I get the file, I want to find the filesize. I hope, I can find this Information within the FileProperties (last line of code).

Then I want to set a FilePointer within that file and to read a defined number of binary data. Can I do that without reading the whole file in memory?

Romasz
  • 29,662
  • 13
  • 79
  • 154
thpitsch
  • 2,016
  • 2
  • 21
  • 27

2 Answers2

4

What you are trying to do is to access LocalFolder, which is not the same as Package.Current.InstalledLocation.

If you want to access files that are included with your package, you can do for example like this - by using URI schemes:

StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///Data/"+fileName));
using (Stream stream = (await file.OpenReadAsync()).AsStreamForRead())
using (BinaryReader reader = new BinaryReader(stream))
{
   Windows.Storage.FileProperties.BasicProperties x = await file.GetBasicPropertiesAsync();
}

or like this - by getting file from your Package, which you can access as StorageFolder - also pay attention here to use correct slashes (as it may be a source of exception):

StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Data\" + fileName);
using (Stream stream = (await file.OpenReadAsync()).AsStreamForRead())
using (BinaryReader reader = new BinaryReader(stream))
{
   Windows.Storage.FileProperties.BasicProperties x = await file.GetBasicPropertiesAsync();
}

Note also that I've put your Stream and BinaryReader into using, as they are IDisposable and it's suitable to release those resources as they are no longer needed.

Note also that when your shared project has a name MySharedProject, you will have to modify the Path of above URI:

StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///MySharedProject/Data/"+fileName));

or obtain the suitable StorageFolder:

StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"MySharedProject\Data\" + fileName);

One remark after discussion:

When you add a file with .txt extension to your project, its Build Action by default is set to Content. But when you add file with .idx extension, as I've checked, its Build Action is set to None by default. To include those files in your package, change them to Content.

Romasz
  • 29,662
  • 13
  • 79
  • 154
  • Thank you for this Long answer. But unfortunately none of the four versions is working. – thpitsch Jun 21 '14 at 09:51
  • Thank you for this Long answer. At least I've learned that LocalFolder is'nt the right place. But unfortunately none of the four versions is working. Now I get FileNotFoundExeptions. Something is wrong with the path. The shared Folder is named "AppName.Shared" as per default when creating an Universal App with Visual Studio 2013. So I've replaced "MySharedProject\Data\" with "Shared\Data\". – thpitsch Jun 21 '14 at 10:00
  • @thpitsch Hmm, if it's not working, check what folders you have in your Package: run in debug mode the line: `var folders = (await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFoldersAsync()).ToList();` - then check container `folders` - it should contain all the folders. Then you can iterate through them and see your Patg. I guess there is something wrong with your path, as I've tried this should work. Oh and I've almost forgot - **I assume that you have added the reference to your Shared project in your Main project**? - without this you won't find those files. – Romasz Jun 21 '14 at 10:49
  • .ToList() is not available for the test code! I've found the same code with ToList() on a Microsoft page, but it is not available! Maybe for other situations but not for C# and Windows Phone 8.1 on VisualStudio 2013. Without ToList() I get a COM Object in folders. I can see a Count of 2 inside, but no Folder names. How to add a reference to the Shared project in the MainProject? In an Universal App, the shared project is linked to both, the Windows 8.1 and the WindowsPhone 8.1 projects. Classes in the shared are available to the other two without any references. – thpitsch Jun 21 '14 at 14:03
  • @thpitsch Add `using System.Linq` to your project – Romasz Jun 21 '14 at 14:10
  • Now Ì've added the data Folder to the main Project and do it with StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///Data/" + fileName)); Also FileNotFound. And yes, the fileName is correct and the file is available. Then I added the file direct to the project without folder. And give the filename as string: StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///d4.idx")); Same FileNotFound. – thpitsch Jun 21 '14 at 14:10
  • Thanks - with Linq the ToList() is available! Now I see two folders: "Assets" (included by Default) and "Programs" (added by myself). No "Data". So I have to ask a new question: How to add data files to the project? – thpitsch Jun 21 '14 at 14:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/56028/discussion-between-romasz-and-thpitsch). – Romasz Jun 21 '14 at 14:24
0

After Romasz has brought me to the right path, I can see the problem is quite different there. My data files were involved in the correct place in the project, but Visual Studio does not bind all what you want. In my project I need large data files to be firmly integrated into the program. These are between 13 KB and 41 MB in size and have file types .idx and .dat. These names are part of the problem.

What I know so far:

I may add .txt files with seemingly arbitrary size. Tested with 41 MB - no problem. The same file with changed file type .idx is not added. The file is simply not included in the compiled project. No error message. Of course I can rename the .idx files to another file type (tested with .id), but I want to know why idx files are treated differently. And why I got no error indication.

thpitsch
  • 2,016
  • 2
  • 21
  • 27
  • By default when you add a file *.txt* to your project its *Build Action* is set to *Content*. But when you add a file *.idx*, its default *Build Action* is set to none - change it to *Content* and your files will be included in the package. – Romasz Jun 22 '14 at 14:28