i would like to create a directory in my isoalted storage and a subdirectory in this directory
i use this method
private void create_directory(string directoryName)
{
try
{
IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
if (!myIsolatedStorage.DirectoryExists(directoryName))
{
myIsolatedStorage.CreateDirectory(directoryName);
myIsolatedStorage.CreateDirectory(directoryName+"/Books");
myIsolatedStorage.CreateDirectory(directoryName + "/EpubBooks");
}
}
catch (Exception ex)
{
// handle the exception
}
}
but when i open the isolated storage explorer i Watch only the directory the two subdirectory are not created
Try to iterate the isolated storage with code. Your subdirs are created:
private void TestDir(string directoryName)
{
var list = new List<string>();
try
{
var myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
if (myIsolatedStorage.DirectoryExists(directoryName))
{
var path = string.Format("{0}\\*", directoryName);
list = myIsolatedStorage.GetDirectoryNames(path).ToList();
}
}
catch
{
}
}
Looks like there is a bug in Isolated Storage Explorer (see the first comment).
Related
I'm trying to export files to the public external storage of an Android phone in Xamarin, for a backup DB. However, in the last version of Android phones (11.0 - API30), one can't opt-out of scoped storage using the property android:requestLegacyExternalStorage="true" of the <application> tag in the manifest.xml.
I made sure that the permissions READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE are granted before trying to create the file. Still, when trying to create a file, a System.UnauthorizedAccessException exception is thrown.
/* file 1: */
// ....
private async void Export_Tapped (object sender, EventArgs e) {
// check if permission for writing in external storage is given
bool canWrite = await FileSystem.ExternalStoragePermission_IsGranted ();
if (!canWrite) {
// request permission
canWrite = await FileSystem.ExternalStoragePermission_Request ();
if (!canWrite) {
// alert user
return;
}
}
// find the directory to export the db to, based on the platform
string fileName = "backup-" + DateTime.Now.ToString ("yyMMddThh:mm:ss") + ".db3";
string directory = FileSystem.GetDirectoryForDatabaseExport (); // returns "/storage/emulated/0/Download"
string fullPath = Path.Combine (directory, fileName);
// copy db to the directory
bool copied = false;
if (directory != null)
copied = DBConnection.CopyDatabase (fullPath);
if (copied)
// alert user
else
// alert user
}
// ....
/* file 2: */
class DBConnection
{
private readonly string dbPath;
// ....
public bool CopyDatabase(string path)
{
byte[] dbFile = File.ReadAllBytes(dbPath);
File.WriteAllBytes(path, dbFile); // --> this is where the exception is thrown <--
return true;
}
// ....
}
So the question stands: how does one write a new file to the public external storage of an Android device with an API level of 29 or more?
All the resources I have found so far, maybe you can gather more information than I did:
https://forums.xamarin.com/discussion/179999/access-denied-to-external-storage
(regarding private external storage) https://forums.xamarin.com/discussion/171039/saving-files-to-external-storage
https://learn.microsoft.com/en-us/xamarin/android/platform/files/external-storage?tabs=windows
https://developer.android.com/about/versions/11/privacy/storage#permissions
Try This , I use a dependency service to call this method in Native Android and save files like docx and pdf from their by byte array.
public async Task<bool> CreateFile(string fileName, byte[] docBytes, string fileType)
{
try
{
Java.IO.File file = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath, fileName + fileType);
OutputStream os = new FileOutputStream(file);
os.Write(docBytes);
os.Close();
}
catch
{
return false;
}
return true;
}
The path you use is incorrect, please try the following file path .
Context context = Android.App.Application.Context;
var filePath = context.GetExternalFilesDir(Android.OS.Environment.DirectoryDocuments);
Refer to https://forums.xamarin.com/discussion/comment/422501/#Comment_422501 .
I need to lowercase all filenames during UploadDirectoryAsync - is this possible to control or set via 'SetAttributesCallback'??
I cannot control the local physical files or rename them locally before uploading them to azure via Azure Storage Data Movement Library.
The end result will be that source and destination filename always will be with lowercase.
Any solution out there??
I need to lowercase all filenames during UploadDirectoryAsync - is this possible to control or set via 'SetAttributesCallback'
Yes, we could do that in the SetAttributesCallback, currently there is no rename Azure blob API, so we could upload the required renamed file in the SetAttributesCallback and delete the UploadDirectoryAsync load file. I also test it on my side, it works correctly.
The following is my demo code.
using System;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.DataMovement;
namespace DataMovementTest
{
class Program
{
static void Main(string[] args)
{
string storageConnectionString = "storage connection string";
CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
CloudBlobClient blobClient = account.CreateCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.GetContainerReference("container name");
blobContainer.CreateIfNotExists();
var destDir = blobContainer.GetDirectoryReference("directory name");
string sourceDirPath = #"local path";
var options = new UploadDirectoryOptions
{
Recursive = false,
BlobType = BlobType.BlockBlob
};
using (MemoryStream journalStream = new MemoryStream())
{
// Store the transfer context in a streamed journal.
DirectoryTransferContext context = new DirectoryTransferContext(journalStream)
{
SetAttributesCallback = (destination) =>
{
CloudBlob destBlob = destination as CloudBlob;
if (System.Text.RegularExpressions.Regex.IsMatch(destBlob.Uri.Segments.Last(), "[A-Z]")) //check whether blobName contains uppercase
{
var path = sourceDirPath + $"/{destBlob.Uri.Segments.Last()}";
Console.WriteLine(path);
var renameBlob = destDir.GetBlockBlobReference(destBlob.Uri.Segments.Last().ToLower());
using (var fileStream = File.OpenRead(path))
{
renameBlob.UploadFromStream(fileStream);
}
destBlob.DeleteIfExists();
}
},
ShouldTransferCallback = (source, destination) => true
};
CancellationTokenSource cancellationSource = new CancellationTokenSource();
try
{
// Start the upload
var uploadResult = TransferManager.UploadDirectoryAsync(sourceDirPath, destDir, options, context, cancellationSource.Token).Result;
}
catch (Exception e)
{
Console.WriteLine("The transfer is cancelled: {0}", e.Message);
}
Console.WriteLine("Files in directory {0} uploading to {1} is finished.", sourceDirPath, destDir.Uri.ToString());
}
}
}
}
I have been using Microsoft Live API for uploading & downloading database. but after downloading or uploading if i tried to access the database in anyway my app gives SqlCeException Unhandled & exits.
If i restart the app before accessing database it doesn't give any errors so for now the solution is
Restart the application
This is my code
IsolatedStorageFileStream fileStream = null;
private void Upload_Click(object sender, RoutedEventArgs e)
{
if (client == null || client.Session == null)
{
MessageBox.Show("You Must Sign In First.");
}
else
{
if (MessageBox.Show("Are You Sure? This Will Overwrite Your Old Backup File!", "Backup?", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
UploadDatabase();
}
}
}
public void UploadDatabase()
{
if (SDFolderID != string.Empty)
{
WLInfo.Text = "Uploading Backup...";
this.client.UploadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(ISFile_UploadCompleted);
try
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
fileStream = store.OpenFile("DB.sdf", FileMode.Open, FileAccess.Read);
client.UploadAsync(SDFolderID, "DB.sdf", fileStream, OverwriteOption.Overwrite);
WLInfo.Text = "Upload Complete.";
}
}
catch
{
WLInfo.Text = "Error: Restart Application.";
}
}
}
private void ISFile_UploadCompleted(object sender, LiveOperationCompletedEventArgs args)
{
if (args.Error == null)
{
client = new LiveConnectClient(session);
client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(GetFiles_GetCompleted);
client.GetAsync(SDFolderID + "/files");
}
else
{
this.WLInfo.Text = "Error Uploading Backup File.";
}
fileStream.Close();
}
void GetFiles_GetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
List<object> data = (List<object>)e.Result["data"];
foreach (IDictionary<string, object> content in data)
{
if (((string)content["name"]).Equals(FileName))
{
FileID = (string)content["id"];
}
}
if (FileID != null)
{
WLInfo.Text = "Backup Found On Sky Drive.";
}
else
{
WLInfo.Text = "Backup Not Found On Sky Drive.";
}
}
I'm guessing it's probably of a Stream not properly closed so your database file is still locked. When you upload or download your database file make sure you use the using statement on all disposable object so that all the Stream are properly disposed automatically
In your code fileStream is not disposed which is probably what is causing the problem (you should "save" this variable in a local filed and call dispose on it in ISFile_UploadCompleted).
Also when if you use using there is no need to call dispose on the object (no need to have store.Dispose();, it's automatically done when you go out of the using scope)
I can not find where is temporary folder to add temp file into.
How do i find?
You just create your own folder and manage the content:
private void SaveTempFile(string fileName, object data)
{
var storage = IsolatedStorageFile.GetUserStoreForApplication();
if (storage.DirectoryExists("temp") == false)
storage.CreateDirectory("temp");
fileName = Path.Combine("temp", fileName);
using (var fileStream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
{
//Write the data
using (var isoFileWriter = new StreamWriter(fileStream))
{
// write your data in the format of your choice
}
}
}
Delete the file whenever you want to
public void DeleteTempFile(string fileName)
{
try
{
var storage = IsolatedStorageFile.GetUserStoreForApplication();
if (storage.DirectoryExists("temp") == false) return;
fileName = Path.Combine("temp", fileName);
if (storage.FileExists(fileName))
{
storage.DeleteFile(fileName);
}
}
catch (Exception) { }
}
There is no that kind of folder prepared for app on Windows Phone. You have to create it on your own and manage clearing the content form there when it's no longer needed. However you don't need to bother about deleting that files when your app is uninstalled - whole application folder is deleted from isolated storage then.
I would really appreciate some help with deleting a file from IsolatedStorage on WP7. I am basically downloading a file from the web, storing it in Isolated Storage and then uploading it to my Downloads folder in my Dropbox. Once I have uploaded it, I would like to delete the file from Isolated Storage, but am getting Exception errors when trying to do so.
Here is my code :
public void readCompleteCallback(Object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
try
{
//string fileName = txtUrl.Text.Substring(txtUrl.Text.LastIndexOf("/") + 1).Trim();
string fileName = searchBox.Text + fileExt;
//string fileName = "DownloadedNZB.nzb";
bool isSpaceAvailable = IsSpaceIsAvailable(e.Result.Length);
if (isSpaceAvailable)
{
// Save mp3 to Isolated Storage
using (var isfs = new IsolatedStorageFileStream(fileName,
FileMode.CreateNew,
IsolatedStorageFile.GetUserStoreForApplication()))
{
long fileLen = e.Result.Length;
byte[] b = new byte[fileLen];
var numberOfBytesRead = e.Result.Read(b, 0, b.Length);
isfs.Write(b, 0, numberOfBytesRead);
isfs.Flush();
isfs.Close();
isf = IsolatedStorageFile.GetUserStoreForApplication();
stream = isf.OpenFile(fileName, FileMode.Open);
MessageBox.Show("File downloaded successfully");
App.GlobalClient.UploadFileAsync("/Public/", fileName, stream, (response) =>
{
MessageBox.Show("Uploaded file to Dropbox OK.");
},
(error) =>
{
MessageBox.Show(error + "Cannot upload file to dropbox.");
});
}
//stream.Close();
isf.DeleteFile(searchBox.Text + fileExt);
}
else
{
MessageBox.Show("Not enough to space available to download the file");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
MessageBox.Show(e.Error.Message);
}
}
I cannot think where I am going wrong, but if someone could point me in the right direction, I would appreciate it.
You are trying to delete file inside using statement, where file is not closed yet
UPD: Your upload is async, so you can delete file only when it completed. Put your code near MessageBox.Show("Uploaded file to Dropbox OK.");