When I delete file like this behind, it throws an exception:
Value does not fall within the expected range.
when deleteasync.
public static async Task DeleteFile(string fileName, string folderPath)
{
try
{
StorageFolder sf = await CheckFolder(folderPath);
StorageFile sfile = await sf.GetFileAsync(fileName);
if (sfile != null)
{
await sfile.DeleteAsync();
}
}
catch (Exception)
{
}
}
Related
I created an app that needs to store user data in a file that is created on Application start and when I compile it, it shows me this System.IO.FileLoadException: Could not find or load a specific file. (Exception from HRESULT: 0x80131621) and this System.NullReferenceException: Invalid pointer.
When the Application starts it calls the Init() Method before everything.
public static class FilesManager
{
public static StorageFolder ROOT_DIRECTORY, USER_DIRECTORY;
public static StorageFile FILES_MANAGER_CACHE_FILE;
public static volatile string FILES_MANAGER_CACHE;
public static volatile StorageFolder FOLDER;
public static async Task Init()
{
try
{
FOLDER = await ApplicationData.Current.LocalFolder.CreateFolderAsync("DashData", CreationCollisionOption.OpenIfExists);
FOLDER = await ApplicationData.Current.LocalFolder.GetFolderAsync("DashData");
if (FOLDER == null) Debug.WriteLine("FOLDER IS NULL.");
FILES_MANAGER_CACHE_FILE = await FOLDER.CreateFileAsync("filesmanageruserdata.json", CreationCollisionOption.OpenIfExists);
FILES_MANAGER_CACHE_FILE = await FOLDER.GetFileAsync("filesmanageruserdata.json");
await LoadFilesManagerCacheAsync();
Debug.WriteLine("TEXT: " + FILES_MANAGER_CACHE);
}
catch(Exception e)
{
Debug.WriteLine("ERROR: " + e.ToString());
}
}
public static async Task LoadFilesManagerCacheAsync()
{
FILES_MANAGER_CACHE = await FileIO.ReadTextAsync(FILES_MANAGER_CACHE_FILE);
}
public static async Task storeUserData(string content)
{
try
{
await FileIO.WriteTextAsync(FILES_MANAGER_CACHE_FILE, content);
}catch(Exception e)
{
Debug.WriteLine("ERROR: " + e.ToString());
}
}
}
I am trapped with definitions of Entity framework and using objects.
I am trying to save an uploaded file once I am saving the details related to that file in my database.
public async Task<IActionResult> Edit(string List<IFormFile> files, [Bind("param")] Entity entity)
{
if (ModelState.IsValid)
{
try
{
_context.Update(entity);
await _context.SaveChangesAsync();
//update Attachments
if (files.Count > 0)
{
attachment.UploadFiles(files);
}
}
catch (DbUpdateConcurrencyException)
{
if (!EntityExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(entity);
}
When I run the application and want to submit the form I receive below error:
Cannot access a disposed object.
Object name: 'FileBufferingReadStream'.
[HttpPost]
public async void UploadFiles(List<IFormFile> files)
{
if (files == null || files.Count == 0)
{
log.error("files not selected");
}
try
{
List<string> filenames = new List<string>();
string directory = Directory.GetCurrentDirectory() + "\\wwwroot";
createDir(directory);
foreach (var file in files)
{
string filename = file.GetFilename();
filenames.Add(filename);
}
if (filenames.Count > 0)
foreach (var filename in filenames)
{
AttachmentQ(filename, directory, createdBy);
}
foreach (var file in files)
{
string filename = file.GetFilename();
var path = Path.Combine(directory, filename);
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
filenames.Add(filename);
}
}
catch (Exception e)
{
log.error(e.Message);
}
}
[ValidateAntiForgeryToken]
public async void AttachmentQ(string filename, string path, string createdBy)
{
try
{
Attachment attachment = new Attachment
{
Name = filename,
Path = path,
CreatedBy = createdBy,
CreatedDate = DateTime.Now
};
_context.Add(attachment);
await _context.SaveChangesAsync();
}
catch (Exception e)
{
log.error(e.Message);
}
}
Surprisingly I don't get error in debug mode. But when I run the app I get This page isn’t working error.
I also noticed I need to return a value when I use async but I don't have any return vale in UploadFiles() and AttachmentQ() methods.
Could you please help me how to handle objects when using different contexts. Thanks
Do NOT use async void at all.
if you want to use async/await pattern then let your methods returns Task
public async Task UploadFiles(List<IFormFile> files)
When i return "FileExist" varable in this code i am getting error..
public static async Task<bool> FileExistsForWp8(string filename)
{
StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
try
{
StorageFile FileExists = await folder.GetFileAsync(filename);
return FileExists;
}
catch (Exception ex)
{
return FileExists;
}
}
The GetFileAsync returns a StorageFile.
Thy this:
public static async Task<bool> FileExistsForWp8(string filename)
{
StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
try
{
StorageFile File = await folder.GetFileAsync(filename);
return true;
}
catch
{
return false;
}
}
I develop a Universal app that use a local SQLite database. As I need to know the database version, I store an additional information that contains this information.
At the application startup, I check if the database exists, and if the database version has changed.
public sealed partial class App : Application
{
// DB Name
public static string DBFileName = "myDb.sqlite";
public static string DBpath;
// DB Version
public static string DBVersionFilename = "myDb.version";
public static string DBVersionPath;
public static string DBVersion = "1.1.0";
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
ManageDB();
}
private async Task ManageDB()
{
if (!CheckDbExist().Result)
{
CreateDb();
}
else
{
if (CheckDbVersionUpdated().Result)
{
await DeleteDb();
CreateDb();
}
}
}
private async Task<bool> CheckDbExist()
{
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync(DBFileName);
DBpath = storageFile.Path;
return true;
}
catch { }
return false;
}
private void CreateDb()
{
try
{
StorageFile storageFile = ApplicationData.Current.LocalFolder.CreateFileAsync(DBFileName, CreationCollisionOption.OpenIfExists).GetResults();
DBpath = storageFile.Path;
var dbconnection = new SQLiteAsyncConnection(DBpath, false);
dbconnection.CreateTableAsync<Article>();
//...
StorageFile file = ApplicationData.Current.LocalFolder.CreateFileAsync(DBVersionFilename, CreationCollisionOption.ReplaceExisting).GetResults();
FileIO.WriteTextAsync(file, DBVersion);
}
catch (Exception e)
{ }
}
private async Task<bool> DeleteDb()
{
try
{
StorageFile storageFile = ApplicationData.Current.LocalFolder.CreateFileAsync(DBFileName, CreationCollisionOption.OpenIfExists).GetResults();
await storageFile.DeleteAsync(StorageDeleteOption.PermanentDelete);
return true;
}
catch { }
return false;
}
private async Task<bool> CheckDbVersionUpdated()
{
try
{
string userDBVersion;
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(DBVersionFilename);
userDBVersion = await FileIO.ReadTextAsync(file);
if (userDBVersion != DBVersion)
return true;
else
return false;
}
catch { }
return false;
}
}
There is a problem on CreateDB():
if I browse this code step by step, with breakpoint, there is no problem
but if I don't place breakpoint I meet an exception after calling var dbconnection = new SQLiteAsyncConnection(DBpath, false);:
System.InvalidOperationException: A method was called at an unexpected time.
A method was called at an unexpected time.
at Windows.Foundation.IAsyncOperation`1.GetResults()
at TestRating.App.CreateDb()}
Would you have an idea about the encountered problem? Is there another way to do this?
When I remove ".Results()" it seems that the "CreateDb()" function works correctly:
private async Task<bool> CreateDb()
{
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(DBFileName, CreationCollisionOption.OpenIfExists);
DBpath = storageFile.Path;
var dbconnection = new SQLiteAsyncConnection(DBpath, false);
dbconnection.CreateTableAsync<Article>();
//...
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(DBVersionFilename, CreationCollisionOption.ReplaceExisting);
FileIO.WriteTextAsync(file, DBVersion);
return true;
}
catch (Exception e)
{ }
return false;
}
Do you have an explanation?
This is basically for windows 8 app and I'm writing a file using this method -
static async void WriteDataCords(int numDataCodewords)
{
StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
var storageFile = await storageFolder.GetFileAsync("DataCodeWords.txt");
string data = numDataCodewords.ToString();
await FileIO.AppendTextAsync(storageFile, data);
}
and now I'm reading file using this method -
StorageFolder storageFolder7 = KnownFolders.DocumentsLibrary;
var storageFile7 = await storageFolder6.GetFileAsync("DataCodeWords.txt");
string text7 = await Windows.Storage.FileIO.ReadTextAsync(storageFile7);
but when I run this program it's throwing an error "Access denied or We can't access the file". Using this approach I'm writing many files and reading.Please let me know how to solve this problem.
Thanks in advance
My problem is when I'm accessing file to read and display at that time file is involve in writing process so thats why I'm unable to access that file and it's showing an error.
So. Is there any approach by which we only move forward when the file writing process is complete and than reading process will start?
You could use SemaphoreSlim which limits the number of threads that can access a resource.
Below is an example of a class that handles writing/reading for a file. You create an instance of it when you want to write a file and call the WriteDataCords method. Then you need some way to access the correct instance when you want to read and then call ReadDataCords:
public class FileReadWrite
{
public string FileName { get; set; }
public FileReadWrite(string fileName)
{
FileName = fileName;
}
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
public async Task WriteDataCords(int numDataCodewords)
{
await _semaphore.WaitAsync();
try
{
StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
var storageFile = await storageFolder.GetFileAsync(FileName);
string data = numDataCodewords.ToString();
await FileIO.AppendTextAsync(storageFile, data);
}
finally
{
_semaphore.Release();
}
}
public async Task ReadDataCords()
{
await _semaphore.WaitAsync();
try
{
StorageFolder storageFolder6 = KnownFolders.DocumentsLibrary;
var storageFile7 = await storageFolder6.GetFileAsync(FileName);
string text7 = await Windows.Storage.FileIO.ReadTextAsync(storageFile7);
}
finally
{
_semaphore.Release();
}
}
}
And calling code:
public class ClientCode
{
public async void WriteFile()
{
var fileReadWrite = new FileReadWrite("DataCodeWords.txt");
await fileReadWrite.WriteDataCords(42);
}
public async void ReadFile()
{
var fileReadWrite = GetFileReadWriteForFile("DataCodeWords.txt"); //Method for retreiving correct instance of FileWriteRead class
await fileReadWrite.ReadDataCords();
}
private FileReadWrite GetFileReadWriteForFile(string fileName)
{
}
}
You could skip the FileWriteRead class (it adds complexity) and use SemaphoreSlim directly in the original code for writing/reading but then you could only write/read one file at a time (which might not be a problem).