Can you access physical drive data from a UWP app? - file-io

I need to overwrite the filesystem of a USB stick with raw data. While a FolderPicker can access e.g. D:\, it can't be used to access e.g. \.\PhysicalDrive1. Is there a way to access physical drive data from a UWP or is it not possible?

You can access USB stick like this:
StorageFolder externalDevices = KnownFolders.RemovableDevices;
StorageFolder usbStick = (await externalDevices.GetFoldersAsync()).FirstOrDefault();
var usbStickFolder = await usbStick.CreateFolderAsync("test", CreationCollisionOption.OpenIfExists);
var file = await usbStickFolder.CreateFileAsync("test.txt", CreationCollisionOption.ReplaceExisting);
But this code would not work before you not set File Type Associations in app manifest. Otherwise it will throw Access Denied exception.

Related

Trouble getting a file from Azure container

I am trying to get a file from Azure container. I need to read its content.
The file has been uploaded to umbraco media, media are stored in our Azure container.
Its normal (umbraco) url would be like:
~/media/10890/filename.xls
I am trying to retrieve it like this:
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["strorageconnstring"]);
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("storagemedia");
The thing is - I am not sure how I am supposed to retrieve a particular file? I tried:
1.
CloudBlobDirectory dira = container.GetDirectoryReference("10890"); // file folder within media
var list = dira2.ListBlobs(useFlatBlobListing: true).ToList(); // Returns error saying "The requested URI does not represent any resource on the server."
However the 10890 folder within media storage exists and I can browse it with storage browser.
2.
CloudBlockBlob blobFile = container.GetBlockBlobReference("10890/filename.xls");
string text;
using (var memoryStream = new MemoryStream())
{
blobFile.DownloadToStream(memoryStream); // Throws "The specifed resource name contains invalid characters." error
var length = memoryStream.Length;
text = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
}
Any idea how to read the file? And what am I doing wrong?
Thank You Gaurav for providing your suggestion in comment section.
Thank You nicornotto for confirming that your issue got resolved by changing the container name reference in the below statement.
var container = blobClient.GetContainerReference("storagemedia");

Can you download a specific Block from an Azure Block Blob?

Is it possible to download a specific block from an Azure Block Blob if you know the Block Id?
Yes, you absolutely can, here's an example of how to download the first block:
var storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net");
CloudBlobClient serviceClient = storageAccount.CreateCloudBlobClient();
var container = serviceClient.GetContainerReference("containerName");
var blockBlob = container.GetBlockBlobReference("blobName");
var blocklist = await blockBlob.DownloadBlockListAsync();
var firstBlock = blocklist.First();
var memStream = new MemoryStream();
await blockBlob.DownloadRangeToStreamAsync(memStream, 0, firstBlock.Length);
string contents;
using (var streamReader = new StreamReader(memStream))
{
contents = await streamReader.ReadToEndAsync();
}
You will need a couple of packages from nuget:
Microsoft.WindowsAzure.Storage
Microsoft.WindowsAzure.Storage.Blob
You could leverage Microsoft Azure Storage SDK for getting started with Azure Blob Storage quickly. And the Azure Storage SDK is a wrapper of Blob Service REST API. From the official tutorial about Blob Service REST API, we couldn't find anything about downloading the specific block via the Block Id. In addition, you could use Get Blob to download the bytes of your blob in the specified range by specifying the offset and the length of data to download from your blob.

Do I need to call CachedFileManager.DeferUpdates in Windows 8 app

In the file picker Windows 8 sample a file is saved like this:
CachedFileManager.DeferUpdates(file);
await FileIO.WriteTextAsync(file, stringContent);
FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
I'm serialising an object as XML so doing it slightly differently:
// CachedFileManager.DeferUpdates(file);
var ras = await file.OpenAsync(FileAccessMode.ReadWrite);
var outStream = ras.GetOutputStreamAt(0);
var serializer = new XMLSerializer();
serializer.Write(myObject, outStream);
// FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
It works with or without the CachedFileManager (commented out above).
So, should I include the CachedFileManager and if I do use it am I saving the file in the right way.
This code works and saves the file fine, but I don't like including code that I don't understand.
Yes, this code will work without CachedFileManager. But, when you use CachedFileManager, you inform the file provider that the file is in process of change. If your file is located on SkyDrive it is faster to create a file and upload it at once instead of update it multiple times.
You can have the full story there : http://www.jonathanantoine.com/2013/03/25/win8-the-cached-file-updater-contract-or-how-to-make-more-useful-the-file-save-picker-contract/
It simply tells the "repository" app to upload the file.

windows 8 modern ui apps - access to data

Where can i find folder with installed modern ui apps? Im developing some app which uses .txt files to store information (win8 doesnot support datebase on arm - facepalm) but they seem to not work properly - thats why i want to access them.
Thanks!
That is not the correct way of doing things in Metro. I assume you mean db files, or txt files. Simply access the local text file from the project folder.
Here is a great tutorial on how you would go about doing so: http://www.codeproject.com/Articles/432876/Windows-8-The-Right-Way-to-Read-Write-Files-in-Win
An example:
private async void ProjectFile()
{
// settings
var _Path = #"Metro.Helpers.Tests\MyFolder\MyFolder.txt";
var _Folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
// acquire file
var _File = await _Folder.GetFileAsync(_Path);
Assert.IsNotNull(_File, "Acquire file");
// read content
var _ReadThis = await Windows.Storage.FileIO.ReadTextAsync(_File);
Assert.AreEqual("Hello world!", _ReadThis, "Contents correct");
}

Storing/Saving XML in local asset folder in AIR

AIR in general seems to be storing the xml file in the path where the app is installed.
I am generating an xml and I want to save/store a xml file in local asset folder of AIR application.
Any thoughts on doing this.
The File class has some static variables that point to local directories:
From the docs:
File.applicationStorageDirectory — a storage directory unique to each installed AIR application
File.applicationDirectory — the read-only directory where the application is installed (along with any installed assets)
File.desktopDirectory — the user's desktop directory
File.documentsDirectory — the user's documents directory
File.userDirectory — the user directory
Creating a pointer to the file
Usually you'll want to store files like these in File.applicationStorageDirectory.
So to create the file do:
File.applicationStorageDirectory.resolvePath("my-config.xml");
Alternatively, you can let the user choose where to store the file by using File#browseForSave(), which will display a native 'save' window to choose the location.
Writing the content
Open a FileStream for the File in 'write' mode and write an XML string to the file.
var fs:FileStream = new FileStream();
fs.open(file, FileMode.WRITE);
fs.writeUTF(myXmlContent);
fs.close();
look at http://www.adobe.com/devnet/air/flex/quickstart/articles/xml_prefs.html
http://www.thetechlabs.com/xml/how-to-build-a-contact-manager-in-air-using-xml-part-2/
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filesystem/File.html
var prefsFile:File = File.applicationStorageDirectory;
prefsFile = prefsFile.resolvePath("preferences.xml");
stream = new FileStream();
stream.open(prefsFile, FileMode.WRITE);
stream.writeUTFBytes(outputStringXML);
Or something like:
var saveStr:String = xmlToSave.toXMLString();
var file:File = new File('app-storage:/data.xml');
var fs:FileStream = new FileStream();
fs.open(file, FileMode.WRITE);
fs.writeUTFBytes(saveStr);
fs.close();