Windows RT : Reading text file from project folder - c#

I'm creating a windows rt application which contains more than 1000 .txt files from which I'm getting their contents.
These text files are part of my project but I can't read them with code.
This is my code
static async Task ReadFile(string filePath, List<string> list)
{
try
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + filePath));
var readThis = await FileIO.ReadLinesAsync(file);
foreach (var line in readThis)
{
list.Add(line);
}
}
catch (FileNotFoundException)
{
}
}
where filePath is : "txt/data/14b.txt.
When code is executed Lists are filled with the data but application crashes and I'm sent in this line of app.g.i.cs
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
any ideas ?

Try marking your text files Build Action as Content. Then
var file = await StorageFile.GetFileFromApplicationUriAsync( new Uri( "ms-appx:///" + filePath ) );
Should load a file.

var storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(String.Format("ms-appx:///{Project name}/txt/data/{0}", fileName)));

Try with replacing
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + filePath));
to
var ProjectFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await ProjectFolder.GetFileAsync(fileName);

Related

uploading a file from local folder to firebase

I am having trouble uploading files(.mp3) stored in the local folder by user to firebase.
This is how a file is retrieved from local folder:
StorageFolder folder = ApplicationData.Current.LocalFolder;
var songfolder = await folder.GetFolderAsync("Songs");
StorageFile mp3file = await songfolder.GetFileAsync(mp3fileforupload);
And this is how I create a stream file of the file and upload:
var stream = File.Open(mp3file.Path, FileMode.Open);
var task = new FirebaseStorage("-my-bucket-.appspot.com")
.Child("songs")
.Child(new_song_id)
.PutAsync(stream);
task.Progress.ProgressChanged += (s, f) => uploadProgress(f.Percentage);
var downloadurl = await task;
Debug.WriteLine("DOWNLOAD_URL " + downloadurl);
The file fails to upload. From the Step-up-labs documentation, the file should be uploaded as a stream of a file. This worked when uploading files from the Assets folder, but does not work with files from local folder. I have tried uploading from the MostRecentlyUsedList but it still fails to upload. Any idea why this is failing?
Try this instead to open the file
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile =
await storageFolder.GetFileAsync(mp3file.Path);
var stream = await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
The Step-Up-Labs C# Firebase-Storage API uses Stream for file uploads. Files should be uploaded as a Stream. What has worked for me is using a Memory Stream.
First I retrieved the file from local folder:
StorageFolder folder = ApplicationData.Current.LocalFolder;
var songfolder = await folder.GetFolderAsync("Songs");
StorageFile mp3file = await songfolder.GetFileAsync(mp3fileforupload);
Then I read the bytes of the file using a DataReader:
byte[] fileBytes = null;
using (IRandomAccessStreamWithContentType stream = await mp3file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (DataReader reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
Then I used a MemoryStream for the upload:
Stream stream = new MemoryStream(fileBytes);
var task = new FirebaseStorage("-my-bucket-.appspot.com")
.Child("songs")
.Child(new_song_id)
.PutAsync(stream);
task.Progress.ProgressChanged += (s, f) => uploadProgress(f.Percentage);
var downloadurl = await task;
That did the trick. The file uploaded.

OneDrive Downloaded *.jpeg Image File Corrupt in Windows Phone 8

I'm doing a backup of my app database to OneDrive. The database records refer to images that are stored in isolated storage. I backup those images too. The database files.
The destinations of the backup file is:
me/skydrive/my_documents/MyCompany/MyApp/MyBackup.bak
The destination of the jpg image files is
me/skydrive/my_documents/MyCompany/MyApp/MyBackup Images/*.jpg
The database restores fine, but the images don't. I've verified that the image is backed up properly on SkyDrive - I can see it and open it fine from SkyDrive. However, when I restore, the file is corrupt. Here's the code I use to restore:
dynamic cmpFolder = await oneDrive.FindFolder("MyCompany", "me/skydrive/my_documents");
dynamic appFolder = await oneDrive.FindFolder(AppName, cmpFolder.id);
string imagesFileName = Path.GetFileNameWithoutExtension(selectedFile.FileName) + " Images";
dynamic imgFolder = await oneDrive.FindFolder(imagesFileName, appFolder.id);
dynamic fileList = await oneDrive.FindFiles(imgFolder.id);
foreach (var fileData in fileList.data)
{
string fileName = fileData.name;
var file =
await wilFolder.CreateFileAsync(
Path.GetFileName(fileName), CreationCollisionOption.ReplaceExisting);
var result = await client.BackgroundDownloadAsync(selectedFile.FileID +
"/content/", new Uri(#"\shared\transfers\" + fileName, UriKind.Relative));
}
Using ISETool and viewing \shared\transfers, I can see that the file is no longer readable. It's size is about 128k, whereas the original image was much larger.
I've also tried this, which was my original code until I began seeing the problem:
var downloadResult = await client.DownloadAsync(selectedFile.FileID + "/content/");
using (Stream oneDriveStream = downloadResult.Stream)
{
oneDriveStream.Position = 0;
byte[] imageBytes = new byte[oneDriveStream.Length];
int count = oneDriveStream.Read(imageBytes, 0, imageBytes.Length);
using (var s = await file.OpenStreamForWriteAsync())
{
oneDriveStream.CopyTo(s);
// and tried this
//s.Write(imageBytes, 0, imageBytes.Length);
}
}
For reference, here's the FindFolder and FindFiles implementations:
public async Task<dynamic> FindFiles(string folderName)
{
LiveOperationResult filesResult = await client.GetAsync(folderName + "/files");
dynamic files = filesResult.Result;
return files;
}
public async Task<dynamic> FindFolder(string folderName, string parentFolder)
{
LiveOperationResult folderResult = await client.GetAsync(parentFolder + "/files?filter=folders");
dynamic folders = folderResult.Result;
foreach (var folder in folders.data)
if (folder.name == folderName)
return folder;
return null;
}
How do I successfully download *.jpg images from my OneDrive folder?
Try this for your download path instead:
var downloadResult = await client.DownloadAsync(selectedFile.FileID + "/picture?type=full");

Can't load XML from file

What is wrong here? It throws ArgumentException
var xmlDocument = await XmlDocument.LoadFromUriAsync(new Uri("ms-appx:///LiveTiles/Templates.xml"));
Is there more simple way to load XML from file?
Thank you!
Windows RT is a little bit special at the time of manipulating files, I highly recommend this blog entry:
http://blog.jerrynixon.com/2012/06/windows-8-how-to-read-files-in-winrt.html
Taken from the link:
// settings
// same as (ms-appx:///MyFolder/MyFile.txt)
var _Folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
_Folder = await _Folder.GetFolderAsync("MyFolder");
// acquire file
var _File = await _Folder.GetFileAsync("MyFile.txt");
Assert.IsNotNull(_File, "Acquire File");
// write content
var _WriteThis = "Hello World";
await Windows.Storage.FileIO.WriteTextAsync(_File, _WriteThis);
Or to simplify it a little bit more, another approach can be:
try
{
StorageFolder storageFolder = Package.Current.InstalledLocation;
StorageFile storageFile = await storageFolder.GetFileAsync("BasicData.xml");
XmlTextBlock.Text = await FileIO.ReadTextAsync(storageFile, Windows.Storage.Streams.UnicodeEncoding.Utf8);
}
catch (Exception ex)
{
XmlTextBlock.Text = ex.Message;
}

Launching PDF reader on windows phone 8

I'm trying to launch pdf reader with the code below but it does not work. Can somebody help me?
private async Task<StorageFile> WriteData(string fileName, byte[] data)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream s = await file.OpenStreamForWriteAsync())
{
await s.WriteAsync(data, 0, data.Length);
s.Close();
}
return file;
}
private async Task<bool> OpenPdf(StorageFile file)
{
var uri = new Uri(file.Path, UriKind.RelativeOrAbsolute);
bool result = await Windows.System.Launcher.LaunchUriAsync(uri);
return result;
}
private async void FetchPdf() {
// Fetch pdf bytes to network
//....
StorageFile file = await WriteData("test.pdf", data);
if (file != null) {
bool result = await OpenPdf(file);
if (result)
Debug.WriteLine("Success");
else
Debug.WriteLine("Cannot open pdf file.");
}
}
result is always false and so launcher is not presented.
I used LaunchUriAsync because LaunchFileAsync is not implemented on Windows Phone.
LaunchUriAsync isn't supported on Windows Phone 8 per the documentation. It throws an exception if called
You can use Windows.System.Launcher.LaunchFileAsync to launch a StorageFile.
This code works for example (assming there's a file called "metro.pdf" in the project, with the Build Action set to Content, with Copy to Output Directory set to Copy if Newer).
var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assets = await installedLocation.GetFolderAsync("Assets");
var pdf = await assets.GetFileAsync("metro.pdf");
Windows.System.Launcher.LaunchFileAsync(pdf);
Called the API and saved the byte array to file
public static async void WriteDataToIsolatedStorageFile(string fileName, byte[] data)
{
using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = storageFile.OpenFile(fileName, FileMode.Create))
{
if ((data != null) && (data.Length > 0))
{
await stream.WriteAsync(data, 0, data.Length);
}
}
}
}
opened the file in pdf reader using
private async void StartExternalPDFApp()
{
StorageFolder localFolder = await FileManager.FindDirectory(FileManager.RelativeStorageDirectoryLocalStorage);
StorageFile storageFile = await localFolder.GetFileAsync(PdfFileName);
await Windows.System.Launcher.LaunchFileAsync(storageFile);
}
localFolder is Windows.Storage.ApplicationData.Current.LocalFolder
just put the anyFile.pdf in Assets folder, and make its build action to Content, and then Just make the function Async ... and then Put "await" before Windows.System.Launcher.LaunchFileAsync(pdf);
it worked fine for me. Nice.
See this.
private async void privacyPolicy_Click(object sender, EventArgs e)
{
var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assets = await installedLocation.GetFolderAsync("Assets");
var pdf = await assets.GetFileAsync("PrivacyPolicy.pdf");
await Windows.System.Launcher.LaunchFileAsync(pdf);
}

Unable to delete a file with DeleteAsync

I'm working in VS2012, WinRT and C#.
I'm trying to delete some files after decompressing them. I'm getting an "Access is denied" error. If I stop the app and re-start it the same code works fine so it appears there is a handle still attached.
If I don't call the unZipFile method, I can delete the files.
Is there a definitive way to release a file? I've set it to null (file = null;) before the call to delete.
Here's the block of code that calls the unzip method:
StorageFile file = await CreateOutputFile(fileName, path);
MemoryStream theMemStream = new MemoryStream();
theMemStream.Write(bytes, 0, bytes.Length);
await FileIO.WriteBytesAsync(file, bytes);
await theMemStream.FlushAsync();
theMemStream.Dispose();
var result = await unZipFile(file, path);
file = null;
Here's the unZipFile method:
private async Task<string> unZipFile(StorageFile file, string path)
{
StorageFolder sf = await GetOutputFolder(path);
using (var zipStream = await file.OpenStreamForReadAsync())
{
using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
{
await zipStream.CopyToAsync(zipMemoryStream);
try
{
var archive = SharpCompress.Archive.ArchiveFactory.Open(file.Path);
foreach (var entry in archive.Entries)
{
entry.WriteTo(zipMemoryStream);
Stream fileData = entry.OpenEntryStream();
StorageFile outputFile = await sf.CreateFileAsync(entry.FilePath, CreationCollisionOption.ReplaceExisting);
using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
{
await fileData.CopyToAsync(outputFileStream);
await outputFileStream.FlushAsync();
outputFileStream.Dispose();
}
}
archive = null;
}
catch (Exception ex)
{
throw new IOException("Error writing decompressed output file: " + ex.Message);
}
await zipStream.FlushAsync();
zipStream.Dispose();
await zipMemoryStream.FlushAsync();
zipMemoryStream.Dispose();
}
}
return "success";
}
Here's the delete method. This is called for each file after decompression:
private async Task<string> deleteFile(string path, string filename)
{
StorageFolder folder = await GetOutputFolder(path);
var files = await folder.GetFilesAsync();
foreach (StorageFile file in files)
{
try
{
if (file != null)
{
if (file.Name == filename)
await file.DeleteAsync();
}
}
catch (Exception ex)
{
return ex.Message;
}
}
return "success";
}
On what file do you get the exception, the extracted files or the zip archive itself?
If the latter is the case, ArchiveFactory.Open() returns an IArchive which inherits IDisposable, so you should wrap var archive = SharpCompress.Archive.ArchiveFactory.Open(file.Path); in a using block so it gets disposed after use.

Categories