I am trying to get an application to write (then read) a simple text file in Windows Phone 8. My app has three controls: a create file button, a display file button, and a textbox where the contents are supposed to display.
I have the following events set up in my code:
private async void btnCreateFile_Click(object sender, RoutedEventArgs e)
{
await ApplicationData.Current.LocalFolder.CreateFileAsync("myFile.txt");
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("myFile.txt");
StreamWriter writer = new StreamWriter(await file.OpenStreamForWriteAsync());
writer.WriteLine("Hello World");
writer.WriteLine("Goodbye world");
}
private async void btnShowFile_Click(object sender, RoutedEventArgs e)
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("myFile.txt");
StreamReader reader = new StreamReader(await file.OpenStreamForReadAsync());
string text = reader.ReadToEnd();
text1.Text = text;
}
}
The application is throwing UnauthorizedAccessException when the StreamReader is being created. Can anyone shed any light on why?
I guess you're not disposing the StreamWriter. See the example on MSDN.
using( var writer = new StreamWriter(await file.OpenStreamForWriteAsync()))
{
writer.WriteLine("Hello World");
writer.WriteLine("Goodbye world");
}
That's why your can't read the file, because it's already taken by SreamWriter.
Always use 'using' statement when using an object that inherits from IDisposable.
You are trying to write to an already opened file and this gives you UnauthoritedException.
Try using your code block inside of using.Check out this question to find more about StreamWriter :
how to use StreamWriter class properly?
Related
I want to be able to have a list of class objects (List<Class>) and be able to easily write and read to a text file.
In my older Console Applications and Windows Forms applications I used to use:
List<Class> _myList = ...
WriteToFile<List<Class>>("C:\\...\\Test.txt", Class _myList)
public static void WriteToFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(filePath, append);
serializer.Serialize(writer, objectToWrite);
}
finally
{
if (writer != null)
writer.Close();
}
}
However this does not work in a UWP application and I have to use StorageFolder and StorageFile which works fine for writing simple text to a file like this:
StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile file= await storageFolder.GetFileAsync("Test.txt");
await FileIO.WriteTextAsync(sampleFile, "Example Write Text");
But I want to be able to use the more advanced functionality of XmlSerializer along with StreamWriter to write lists of classes to a file within my UWP application.
How can I do this?
You can use the Stream-based versions the methods you use, for example StreamWriter has a constructor which takes a System.IO.Stream instance.
To get a System.IO.Stream from a StorageFile, you can use the OpenStreamForWriteAsync and OpenStreamForReadAsync extension methods, which are in the System.IO namespace on UWP:
//add to the top of the file
using System.IO;
//in your code
var stream = await myStorageFile.OpenStreamForWriteAsync();
//do something, e.g.
var streamWriter = new StreamWriter(stream);
this is my code to fill my txt file, and show in my application.
StreamWriter file = new StreamWriter("opslag_kentekens",true);
string opslag_kentekens = textBox1.Text;
file.WriteLine(opslag_kentekens);
file.Close();
label20.Text = File.ReadAllText("opslag_kentekens");
My question is: how do i clear my txt file when i exit my application?
Clearing of text file is pretty straightforward: just write empty string into it:
StreamWriter file = new StreamWriter("opslag_kentekens", false);
file.Write(String.Empty);
file.Close();
Catching application exit depends on framework you're using in your application.
For example, on WinForms (it looks like you're using it) you can override OnFormClosed method of your main application form and to your file clearing there:
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
//clear your file
}
Or you can handle Application.ApplicationExit event and clear your file from there.
I had the following code dispersed throughout my program. However I always seem to get the error below. Even though I am using a "using bracket" to dispose of resources I still don't know why this is happening.
Error:
The Process cannot access the file "the file path" because it is being used by another process.
Code:
string folderpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AGoogleHistory");
string filecreate;
private void restoreTbasToolStripMenuItem_Click(object sender, EventArgs e)
{
using(StreamReader sr = new StreamReader(filecreate))
{
string s = sr.ReadToEnd();
MessageBox.Show(s, "History", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
try
{
browser.Navigate(new Uri(Address));
using(StreamWriter sw = new StreamWriter(filecreate))
{
sw.WriteLine(Address);
}
}
catch(System.UriFormatException)
{
return;
}
private void clearToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are You Sure", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
{
File.Delete(filecreate);
}
else
{
}
}
I think you should first check that file is exists or not by
File.Exists(filePath);
Second thing you are passing wrong parameter to StreamReader class which is an empty string as you haven't assigned anything to it. Check above mentioned things first and you can refer below link for your ease :
The process cannot access file...
Let me know if you have any other issue after trying this.
StreamReader, by default, locks the file. This causes the error you are seeing. Luckily, StreamReader accepts a stream as one of it's overloads for it's constructor. This allows you to first create a FileStream, which has a handy enum allowing you to specify read/write sharing, then pass that FileStream to your StreamReader for use.
So in your case:
using(StreamReader sr = new StreamReader(filecreate))
...
becomes:
FileStream fs = new FileStream(filecreate, FileMode.Open, FileShare.ReadWrite);
using(StreamReader sr = new StreamReader(fs))
...
For more info, see the question below. It's essentially the same question, just asked differently. The accepted answer should explain a bit more.
How to open a StreamReader in ShareDenyWrite mode?
EDIT
Looking over your question again, I see that part of your problem is you don't close your streams. They should get closed when the using block exits, but it's best practice to close them yourself with sr.Close();
Also, you may need to add the delete flag to the fileshare option:
FileStream fs = new FileStream(filecreate, FileMode.Open, FileShare.ReadWrite|FileShare.Delete);
using(StreamReader sr = new StreamReader(fs))
...
I would like to set up a set of local text 'data' files and display them on a windows 8 app.
I can use something like this in a class:
public async void readFile()
{
StorageFile storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Box__The.txt"));
Stream stream = await storageFile.OpenStreamForReadAsync();
StreamReader streamReader = new StreamReader(stream);
_strFile = streamReader.ReadToEnd();
}
which reads the file into a text string correctly and I can see that when I step through the code, but when I try to pass the result back to the main display code, it shows it as null.
Is this some issue to do with threads or something?
try
{
await readFile();
label.Text = _strFile ;
}
catch (Exception ex)
{
// An exception occurred from the async operation
}
I have build an app with a webbrowser in it. It's working fine but when I try to navigate to an adress like bla.pdf the webbrowser shows nothing.
I solved this problem with automatically open the Internet Explorer if the adress is linking to a pdf file.
Is there a better solution? I want to open that PDF file in my own app and I dont want to open the Internet Explorer everytime. Any suggestions?
If you've got a locally downloaded PDF that is in Isolated Storage you can launch the PDF Reader application (or any other applications registered to open PDF files) using LaunchFileAsync.
private async void LaunchFileButton_Click(object sender, RoutedEventArgs rea)
{
// Access isolated storage.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Access the PDF.
StorageFile pdfFile = await local.GetFileAsync("file1.pdf");
// Launch the bug query file.
Windows.System.Launcher.LaunchFileAsync(pdfFile);
}
(adapted from MSDN, see section on "launching a file").
If it's a remote URL then you can use LaunchUriAsync (which will use IE to download the file first).
You will need to try this on a device with the PDF Reader application installed - it won't work on the Emulator.
You should read following article if you are not familiar with Async: MSDN Asynchronous Programming with Async and Await
I couldn't test my app because my WP8 Phone is currently not available and I can't install an PDF reader on the emulator.
Call following method to start the download
WebClient pdfDownloader = null;
string LastFileName = ""; //To save the filename of the last created pdf
private void StartPDFDownload(string URL)
{
pdfDownloader = new WebClient(); //prevents that the OpenReadCompleted-Event is called multiple times
pdfDownloader.OpenReadCompleted += DownloadPDF; //Create an event handler
pdfDownloader.OpenReadAsync(new Uri(URL)); //Start to read the website
}
async void DownloadPDF(object sender, OpenReadCompletedEventArgs e)
{
byte[] buffer = new byte[e.Result.Length]; //Gets the byte length of the pdf file
await e.Result.ReadAsync(buffer, 0, buffer.Length); //Waits until the rad is completed (Async doesn't block the GUI Thread)
using (IsolatedStorageFile ISFile = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
LastFileName = "tempPDF" + DateTime.Now.Ticks + ".pdf";
using (IsolatedStorageFileStream ISFileStream = ISFile.CreateFile(LastFileName))
{
await ISFileStream.WriteAsync(buffer, 0, buffer.Length);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + ex.HResult,
ex.Source, MessageBoxButton.OK);
//Catch errors regarding the creation of file
}
}
OpenPDFFile();
}
private async void OpenPDFFile()
{
StorageFolder ISFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
try
{
IStorageFile ISFile = await ISFolder.GetFileAsync(LastFileName);
await Windows.System.Launcher.LaunchFileAsync(ISFile);
//http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206987%28v=vs.105%29.aspx
}
catch (Exception ex)
{
//Catch unknown errors while getting the file
//or opening the app to display it
}
}
To call these methods from your WebBrowser-Control you need to catch the navigating event.
YourWebBrowserControl.Navigating += YourWebBrowserControl_Navigating;
void YourWebBrowserControl_Navigating(object sender, NavigatingEventArgs e)
{
if(e.Uri.AbsolutPath.EndsWith("pdf"))
{
StartPDFDownload(e.Uri.ToString());
}
}
Don't forget that you'll have to delete the files created someday.
Try this to open a PDF from a WebControl:
void MyWebBrowserControl_Navigating(object sender, NavigatingEventArgs e)
{
if (e.Uri.AbsolutPath.ToLower().EndsWith(".pdf"))
{
var success = Windows.System.Launcher.LaunchUriAsync(e.Uri);
}
}