I'm trying to read data from json file in .NET 4.5 for Windows Phone app. After pressing button the exception appears saying:
System.IO.FileNotFoundException (Exception from HRESULT: 0x80070002)
My code:
public static async Task ReadFile()
{
StorageFolder local = Windows.ApplicationModel.Package.Current.InstalledLocation;
if (local != null)
{
var file = await local.OpenStreamForReadAsync("bazaDanych.json");
using (StreamReader streamReader = new StreamReader(file))
{
json = streamReader.ReadToEnd();
}
}
}
Here's my view of Solution Explorer:
You're not copying your file to the local storage.
Put your json file under the Assets folder, make sure that it's properties says "Content" and "Copy Always"
On the first launch you should read the json from the package
var filename = "Assets/BazaDanych.json";
var sFile = await StorageFile.GetFileFromPathAsync(filename);
var fileStream = await sFile.OpenStreamForReadAsync();
And store into the local storage.
There is an example for Windows 8 (which is more or less the same)
Related question.
Related
I'm currently trying to port my WPF C# App to android and iOS using Xamarin Forms. I have a .txt file in the assets folder in the Xamarin Android project, and I'm trying to read its contents using:
string path =Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),filename);
List<string> FENs = new List<string>();
string Puzzles;
Puzzles = File.ReadAllText(path);
the filename is "puzzles.txt", which is the txt I want to read from the assets folder. However, I keep getting the FileNotFoundException with this report: 'Could not find file "/data/user/0/com.companyname.stockfish_wins/files/.local/share/puzzles.txt"'
the solution's name is Stockfish Wins.
You could use the Asset Manager https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/resources-in-android/android-assets?tabs=windows#reading-assets
// Read the contents of our asset
string content;
AssetManager assets = this.Assets;
using (StreamReader sr = new StreamReader (assets.Open ("read_asset.txt")))
{
content = sr.ReadToEnd ();
}
I'd suggest using Xamarin.Essentials instead of trying to read the file from the correct location yourself https://learn.microsoft.com/en-gb/xamarin/essentials/get-started?tabs=windows%2Candroid
Once installed you can use the File Sytem Helper to access a file within Assets (Android) or Resources (iOS) https://learn.microsoft.com/en-gb/xamarin/essentials/file-system-helpers?context=xamarin%2Fandroid&tabs=android
using (var stream = await FileSystem.OpenAppPackageFileAsync(templateFileName))
{
using (var reader = new StreamReader(stream))
{
var fileContents = await reader.ReadToEndAsync();
}
}
I'm trying to add multiple files to an already created ZIP file using PickMultipleFilesAsync(). I previously created the ZIP file I want to access in the same code using FilesavePicker.PickSaveFileAsync() method. The app is running on Windows 10 Pro version 1803 in Laptop PC, and I used Visual Studio Community 2017 to create it.
The problem I get is that, after following steps described in the FileOpenPicker MSDN page, I get a System.UnauthorizedAccessException: 'Access to the path 'C:\Users\'User'\Downloads{ZIP file}' is denied.'
I created ZIP file and tried to add new files using this code:
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
// Prevent updates to the remote version of the file until we finish making changes and call CompleteUpdatesAsync.
CachedFileManager.DeferUpdates(file);
try
{
Stream stream = await file.OpenStreamForWriteAsync();
using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Update))
{
// This line works fine, file is added
archive.CreateEntryFromFile(path_to_another_file, file_name_in_ZIP);
//....
var dialog = new MessageDialog("Do you want to add more files to ZIP?");
//... (dialog configuration for Yes/No options)
var result = await dialog.ShowAsync();
if(result.Label == "Yes")
{
Debug.WriteLine("Yes option was selected!");
// Include additional files
var openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add("*");
openPicker.SuggestedStartLocation = PickerLocationId.Downloads;
IReadOnlyList<StorageFile> addedFiles = await openPicker.PickMultipleFilesAsync();
if (addedFiles.Count > 0)
{
// Application now has read/write access to the picked file(s)
foreach (StorageFile addedFile in addedFiles)
{
Debug.WriteLine(addedFile.Path); // No problem here
// I get the UnauthorizedAccessException here:
archive.CreateEntryFromFile(addedFile.Path, #"additional files/" + addedFile.Name);
}
}
else
{
// Update log file
globalLog += GetTime() + "No additional files";
}
}
}
}
}
I already added <rescap:Capability Name="broadFileSystemAccess"/> to appxmanifest just in case, but as I had access to selected files using FileOpenPicker I think that is not the problem.
As I created the ZIP file within this code I should still have access to it, right? I suspect that FileOpenPicker somehow "closes" access to ZIP file in order to give access to files to be added, or that MessageDialog prevents of accessing the ZIP file I created after I called showAsync().
Is there any other way to achieve what I'm trying?
EDIT: I can not access the file(s) I select using FileOpenPicker, despite I can show file name(s) in Debug console. ZIP file access is OK.
I just found a solution. As stated here, you can use a buffer to stream file contents to ZIP file, just replace:
// I get the UnauthorizedAccessException here:
archive.CreateEntryFromFile(addedFile.Path, #"additional files/" + addedFile.Name);
With:
ZipArchiveEntry readmeEntry = archive.CreateEntry(#"additional files/" + addedFile.Name);
byte[] buffer = WindowsRuntimeBufferExtensions.ToArray(await FileIO.ReadBufferAsync(addedFile));
using (Stream entryStream = readmeEntry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
That way, files are added and no UnauthorizedAccessException happens. Hope this helps anyone with the same problem!
I'm trying to create a file explorer for windows 10 mobile
I need to launch files with default app from pathes (not installed directory)
ex. "d:\test.pdf"
Here's what I've tried:
string p = #"a.jpg";
StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
StorageFile file = await externalDevices.GetFileAsync(p);
var success = await Launcher.LaunchFileAsync(fff);
you can use Windows.System.Launcher API to launch the default handler for a file you can read more here
async void DefaultLaunch()
{
// Path to the file in the app package to launch
string imageFile = #"images\test.png";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
if (file != null)
{
// Launch the retrieved file
var success = await Windows.System.Launcher.LaunchFileAsync(file);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
else
{
// Could not find file
}
}
If you want to access files from SD card, please make sure that you have read the What you can and can't access on the SD card section on document.
Your app can only read and write files of file types that the app has registered to handle in the app manifest file.
Your app can also create and manage folders.
Make sure that you check "Removable Storage" in the capabilities of the appxmanifest.
You must declare a file type association in the Package.appxmanifest in order to read files from the SD card. The following is an example of one that I set up:
Then, I used the following code sample to launch a picture which is contained in "New folder" on SD card successfully.
string p = #"1.jpg";
StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
var rootfolder = (await externalDevices.GetFoldersAsync()).FirstOrDefault();
var folder = await rootfolder.GetFolderAsync("New folder");
var file = await folder.GetFileAsync(p);
var success = await Launcher.LaunchFileAsync(file);
I'm trying to read/write some text files from Local Storage:
KnownFolders.DocumentsLibrary
I have a simple text file that is stored in 'Documents' in my OneDrive folder, and I can read that fine. But when I write out another text file it gets created in my local 'Documents' folder for my PC, not the OneDrive folder. Why is that when I'm pointing to the same folder for both reading and writing, it reads from one location, but writes to another? Here is the method:
public static async void MyMethod()
{
var myFolder = KnownFolders.DocumentsLibrary;
Stream myStream = await myFolder.OpenStreamForReadAsync("readFromHere.txt");
string fileContents = "";
using (StreamReader streamReader = new StreamReader(myStream))
fileContents = streamReader.ReadToEnd();
var outputFile = await myFolder.CreateFileAsync("writeToHere.txt", CreationCollisionOption.OpenIfExists);
await FileIO.WriteTextAsync(outputFile, fileContents);
}
I try to upload a text file to my skydrive or at least create new text file in SD and edit it's content, through SkyDrive API in my Windows 8 application.
How can I do that?
I tried to do something like that:
LiveConnectClient client = new LiveConnectClient(session);
var fileData = new Dictionary<string, object>();
fileData.Add("name", "new_file.txt");
try
{
LiveOperationResult fileOperationResult = await client.PutAsync("me/skydrive", fileData);
this.infoTextBlock.Text = fileOperationResult.ToString();
}
catch (LiveConnectException exception)
{
this.infoTextBlock.Text = exception.Message;
}
but I get error
"The provided request is not valid. The root SkyDrive folder cannot be updated."
If I write something like "me/skydrive/" I get
"The provided URL is not valid. The requested path '' is not supported".
Method LiveConnectClient.PutAsync allows me only to update existing properties (but not it's content).
How it should be done properly?
Btw - Is content on LCDC(http://msdn.microsoft.com/en-us/library/live/hh826531.aspx) updated? I'm asking because some methods, which are in documentation, doesn't exist in dlls (f.e. LiveConnectClient.Upload. There's only BackgroundUploadAsync).
Thanks for help in advance,
Micheal
Close but as I wrote: I can't use client.upload method because LiveConnectClient class doesn't contain it. That's why I asked about site content update.
Anyway - I've got an answer:
//create a StorageFile (here is one way to do that if it is stored in your ApplicationData)
StorageFile file = awaitApplicationData.Current.LocalFolder.GetFileAsync("yourfilename.txt");
try {
client = new LiveConnectClient(session);
LiveOperationResult operationResult = await client.BackgroundUploadAsync("me/skydrive", file.Name, file, OverwriteOption.Overwrite);
}
catch (LiveConnectException exception) {
//handle exception
}
You should use the Upload method on LiveConnectionClient. For example, see the Uploading Files example in the Live SDK. Something like ...
LiveOperationResult fileOperationResult =
await client.Upload("me/skydrive", /*file name here*/, /*file stream here*/);
Here's another way to upload a file from a console application using a SkyDriveApiClient downloaded from http://skydriveapiclient.codeplex.com/releases/view/103081
static void Main(string[] args)
{
var client = new SkyDriveServiceClient();
client.LogOn("YourEmail#hotmail.com", "password");
WebFolderInfo wfInfo = new WebFolderInfo();
WebFolderInfo[] wfInfoArray = client.ListRootWebFolders();
wfInfo = wfInfoArray[0];
client.Timeout = 1000000000;
string fn = #"test.txt";
if (File.Exists(fn))
{
client.UploadWebFile(fn, wfInfo);
}
}