Chips
Chips

Reputation: 69

UWP how to get access to file in folder

Help me please, I can't get access to file which I choose by FileOpenPicker.

FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.Desktop;
openPicker.CommitButtonText = "Открыть";
openPicker.FileTypeFilter.Add(".xlsx");
var file = await openPicker.PickSingleFileAsync();

using (FileStream fs = new FileStream(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{

}

What is wrong?

Upvotes: 1

Views: 904

Answers (3)

PingZing
PingZing

Reputation: 950

Because of how UWP sandboxes access to the filesystem, you can't construct a FileStream directly from a StorageFile's path. Instead, you have a few options, in order from simplest to most complex:

1) If your file is small enough, you can just use the helpers in the FileIO static class to read it all at once:

string text =  await FileIO.ReadTextAsync(file); // or ReadLinesAsync or ReadBufferAsync, depending on what you need

2) Use the OpenAsync() method on StorageFile:

using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read, StorageOpenOptions.AllowReadersAndWriters)) 
{
     // your reading code here
}

If you need to, you can convert between IRandomAccessStream and .NET Streams with the AsStream(), AsStreamForRead() and AsStreamForWrite() extension methods on IRandomAccessStream, the docs for which are here.

3) If you want complete control, you can get a SafeFileHandle to the underlying file using CreateSafeFileHandle(), like so:

SafeFileHandle fileHandle = file.CreateSafeFileHandle(FileAccess.Read, FileShare.ReadWrite);

You can then use this file handle to create a standard FileStream:

using (FileStream fs = new FileStream(fileHandle, FileAccess.Read))
{
     // Read stuff here
}

This is the only way to reliably use a FileStream on a UWP StorageFile, and should be used with some caution. The official docs have more details on the implications of doing this.

Upvotes: 5

Nico Zhu
Nico Zhu

Reputation: 32775

Please avoid use file Path to access file stream in UWP platform, if you have get the file with FileOpenPicker. You could get the file stream with following.

FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.Desktop;
openPicker.CommitButtonText = "Открыть";
openPicker.FileTypeFilter.Add(".xlsx");
var file = await openPicker.PickSingleFileAsync();
if (file != null)
{      
 var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
}

And if you need use stream in System.IO namespace. please call AsStream method for IRandomAccessStream object.

var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
System.IO.Stream iostream = stream.AsStream();

For more detail please refer this official document.

Upvotes: 0

Martin Zikmund
Martin Zikmund

Reputation: 39072

FileOpenPicker gives you a StorageFile which wraps the opened files and gives you permission to it. This doesn't give you access to the file in general - e.g. you cannot use its Path only to open it with a FileStream. Instead, you need to use the respective Windows.Storage APIs to do this. I usually use the OpenStreamForReadAsync extension method. Add using System.IO to the file header and then:

var stream = await file.OpenStreamForReadAsync();

This method returns a System.IO.Stream which you can use with classic System.IO-enabled APIs.

Upvotes: 1

Related Questions