Dispose an object that is used in the constructer of another object - c#

I am using this code to read values from an isolated storage
IsolatedStorageFile isoStore = null;
StreamReader reader = null;
IsolatedStorageFileStream isolatedStorageFileStream = null;
String strIsolatedStorageValue = string.Empty;
isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
try
{
isolatedStorageFileStream = new IsolatedStorageFileStream(strKey + ".txt", FileMode.OpenOrCreate, isoStore);
// This code opens the store and reads the string.
reader = new StreamReader(isolatedStorageFileStream);
// Read a line from the file and add it to sb.
strIsolatedStorageValue = reader.ReadLine();
}
catch (Exception)
{
}
finally
{
if (isolatedStorageFileStream != null)
{
isolatedStorageFileStream.Dispose();
}
if (reader != null)
{
reader.Dispose();
}
}
// Return the string.
return strIsolatedStorageValue;
The problem is that when I am disposing isolatedStorageFileStream and then disposing the reader, visual studio tells me that isolatedStorageFileStream could be disposed more than once! and when not disposing it I am getting the warning that isolatedStorageFileStream should be disposed first.
What to do in such a case, that is disposing an object used in the constructor of another disposable object
Thanks

You should dispose the reader before the filestream.
To simplify your code, you should make use of using blocks. They do the try/finally/dispose pattern automagically for you:
using (isolatedStorageFileStream = new IsolatedStorageFileStream(
strKey + ".txt", FileMode.OpenOrCreate, isoStore)) {
// This code opens the store and reads the string.
using (reader = new StreamReader(isolatedStorageFileStream)) {
strIsolatedStorageValue = reader.ReadLine();
}
}

Use the using keyword:
using (IsolatedStorageFileStream isolatedStorageFileStream =
new IsolatedStorageFileStream(
strKey + ".txt", FileMode.OpenOrCreate, isoStore))
using (StreamReader reader = new StreamReader(isolatedStorageFileStream))
{
// Read a line from the file and add it to sb.
strIsolatedStorageValue = reader.ReadLine();
}
return strIsolatedStorageValue;
using safely calls Dispose for you and you don't have to call it manually.

The using statement automatically does try-finally for IDisposable (dispose if not null) for you.
using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream(strKey + ".txt", FileMode.OpenOrCreate, isoStore))
{
using (StreamReader reader = new StreamReader(isolatedStorageFileStream))
{
string strIsolatedStorageValue = reader.ReadLine();
return strIsolatedStorageValue;
}
}

Related

The process cannot access the file because it is being used by another process

public bool ReadFile()
{
string fname = "text.txt";
FileStream fs = null;
fs = new FileStream(fname, FileMode.OpenOrCreate,FileAccess.Read);
StreamReader sr = new StreamReader(fs);
string res = sr.ReadToEnd();
if (res == "1")
return true;
else
return false;
}
public void WriteToFile()
{
string fname = "text.txt";
FileStream fs = null;
fs = new FileStream(fname, FileMode.Open,FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.Write("1");
}
So it should work like if ReadFile returns false than i do WriteFile.
But when it reaches writefile, it throws IO expection:
The process cannot access the file ... because it is being used by another process
You aren't closing the file when you read it.
Put your FileStream and StreamReader objects in using statements:
using (var fs = new FileStream(fname, FileMode.OpenOrCreate,FileAccess.Read)) {
using (var sr = new StreamReader(fs)) {
//read file here
}
}
Make sure you do the same when you write to the file.
You need to dispose the StreamReader object in the ReadFile method. The StreamReader inherits from IDisposable and therfor you need to dispose the object.
Check this link for more info:StreamReader Class

Cannot create file "c:\User\...\Appdata\Roaming...". Access is denied

I want to store certain .txt file during app lifetime. I was thinking to use Environment.SpecialFolder.ApplicationData
so I created
string myFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), address.GetHashCode() + ".txt");
...
File.WriteAllText(myFilename, someTextContent);
I'm getting
Cannot create file "c:\User...\Appdata\Roaming...". Access is denied.
Consider using Isolated Storage, you have guaranteed read/write access with it.
Writing:
IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("TestStore.txt", FileMode.CreateNew, isoStore))
{
using (StreamWriter writer = new StreamWriter(isoStream))
{
writer.WriteLine("Hello Isolated Storage");
}
}
Reading:
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("TestStore.txt", FileMode.Open, isoStore))
{
using (StreamReader reader = new StreamReader(isoStream))
{
string contents = reader.ReadToEnd();
}
}

Operation not permitted on IsolatedStorageFileStream in WP8

I have seen numerous similar questions and I have really tried all the solutions but none seems to work for me.
This is what I have now:
private readonly object _lock = new object();
List<DataModel> dataList = new List<DataModel>();
lock (_lock)
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
dataList = (List<DataModel>)serializer.Deserialize(stream);
}
}
catch (IsolatedStorageException e) { e.ToString(); }
}
}
The error occurs on the line using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)).
I deduced from the other solutions that I read that this error mainly occurs when I want to write to the file while others are reading it or execute that code block several times concurrently, I end up locking the file."
With the presence of the lock, FileAccess.ReadWrite and FileShare.ReadWrite statements, I'm pretty sure something else is throwing that exception.
My question is what could be throwing the exception (IsolatedStorageException) and how do I take care of it?
There is no InnerException on this one.
Edit: Upon Kookiz suggestion, I'm including this code lines
First, I create my .xml file like this:
public static void createDataXML()
{
List<DataModel> dataList = new List<DataModel>();
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists("Data.xml"))
{ return; }
using (IsolatedStorageFileStream stream = myIsolatedStorage.CreateFile("Data.xml"))
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
serializer.Serialize(stream, dataList);
}
catch
{ }
}
}
}
Later, I populate with this code:
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
using (XmlWriter xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
{
serializer.Serialize(xmlWriter, dataList);
}
}
}
I know this is a less conventional way of doing this but it IS a way. I was attempting to do something else and this was the result. Just add in the known type you need and this will work
[DataContractAttribute]
[KnownType (typeof(List<String>))]
public class SerializableObject
{
[DataMember]
public List<String> serFile { get; set; }
}
public static Object GetFile(String FileName)
{
try
{
if (!IsolatedStorageFile.GetUserStoreForApplication().FileExists(FileName))
{
throw new System.ArgumentException("File Doesn't Exist In Isoloated Storage");
}
}
catch { return null; }
Object ret = new Object();
try
{
IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(#"\" + FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
SerializableObject serList = new SerializableObject();
DataContractSerializer dsc = new DataContractSerializer(serList.GetType());
ret = ((SerializableObject)dsc.ReadObject(fileStream)).serFile;
}
catch (Exception error) { throw new System.ArgumentException(error.Message); }
return ret;
}
The implied task here is that you need to serialize it within a SerializableObject instance. Let me know if you need that code also
Edit
As promised, the savefile function
public static void SaveFile(String FileName, List<String> File)
{
try
{
if (FileName.Length < 1)
{
throw new System.ArgumentException("File Name Must Not Be Empty");
}
if (IsolatedStorageFile.GetUserStoreForApplication().AvailableFreeSpace <= 0)
{
throw new System.ArgumentException("Isolated Storage Out of Memory - Please free up space.");
}
if (IsolatedStorageFile.GetUserStoreForApplication().FileExists(FileName))
{
throw new System.ArgumentException("File Already Exists - Please choose a unique name.");
}
if (File == null)
{
throw new System.ArgumentException("Cannot Save Null Files");
}
}
catch (Exception e)
{
return;
}
try
{
SerializableObject so = new SerializableObject() { serFile = File };
DataContractSerializer dsc = new DataContractSerializer(so.GetType());
IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
StreamWriter writer;
writer = new StreamWriter(new IsolatedStorageFileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, file));
dsc.WriteObject(writer.BaseStream, so);
}
catch (Exception error) { throw new System.ArgumentException(error.Message); }
}
Enjoy serializing!
My dear, though this exception of Operation Not Permitted On IsolatedStorage is mainly due to ReadWrite by another thread, in your case it is because of ONE SIMPLE REASON
FileMode.Open throws exception when the filename DOES NOT EXIST
Try with FileMode.OpenOrCreate and it will work like a charm
List<DataModel> dataList = new List<DataModel>();
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
dataList = (List<DataModel>)serializer.Deserialize(stream);
}
}

WIndows Phone 7 reading file to String

I'm trying to read a file entirely to a String variable.
I did this:
String text;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var readStream = new IsolatedStorageFileStream("k.dat", FileMode.Open, store))
using (var reader = new StreamReader(readStream))
{
text= reader.ReadToEnd();
}
textBlock1.Text = text;`
It gave me a "Operation not permitted on IsolatedStorageFileStream" message from an IsolatedStorageException.
What am I doing wrong?
I tried by adding a .txt and .xml file in the file name, but it didn't work.
Where am I to put the file anyway? I tried
~\Visual Studio 2010\Projects\Parsing\Parsing\k.dat
I'm parsing it later using:
XmlReader reader = XmlReader.Create(new StringReader(xmldata));
flagLink = false;
while (reader.Read())
{
//and so on
Try with..
string text;
string filename="k.txt";
using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isolatedStorage.FileExists(fileName))
{
StreamReader reader = new StreamReader(new IsolatedStorageFileStream(fileName, FileMode.Open, isolatedStorage));
text = reader.ReadToEnd();
reader.Close();
}
if(!String.IsNullOrEmpty(text))
{
MessageBox.Show(text);
}
}
EDIT:
In case of xml,
try
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageFileStream isoFileStream = myIsolatedStorage.OpenFile("test.xml", FileMode.Open); //you can use your filename just like above code
using (StreamReader reader = new StreamReader(isoFileStream))
{
this.textbox1.Text = reader.ReadToEnd();
}
}
}
catch
{ }
This is the entire method and this worked fully:
String sFile = "k.dat";
IsolatedStorageFile myFile = IsolatedStorageFile.GetUserStoreForApplication();
//myFile.DeleteFile(sFile);
if (!myFile.FileExists(sFile))
{
IsolatedStorageFileStream dataFile = myFile.CreateFile(sFile);
dataFile.Close();
}
var resource = Application.GetResourceStream(new Uri(#"k.dat", UriKind.Relative));
StreamReader streamReader = new StreamReader(resource.Stream);
string rawData = streamReader.ReadToEnd();
return rawData;

FileStream.WriteLine() is not writing to file

I am trying to make a simple software which stores data in a TXT log file.
This is my code
FileStream fs = null;
StreamWriter fw = null;
try
{
fs= new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"/textme.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
fw = new StreamWriter(fs);
fw.Write("sadadasdsadsadsadas");
for (int i = 0; i < AnimalShelter.AnimalList.Count; i++)
{
fw.WriteLine("<chipNr>" + AnimalShelter.AnimalList[i].ChipRegistrationNumber + "<chipNr>");
Console.WriteLine("<chipNr>" + AnimalShelter.AnimalList[i].ChipRegistrationNumber + "<chipNr>");
}
}
catch(IOException)
{
MessageBox.Show("ERROR THROWN");
}
finally
{
if (fs!= null) fs.Close();
// if (fw != null) fw.Close();
}
What I achieved is: the file gets created, but nothing gets written in it.
I checked a lot of posts but I could not find any particular help.
Adding a call to Flush the stream works. This is because you are wrapping the FileStream. StreamWriter will write to the FileStream, but you need to indicate when to send the Stream to the actual file. Also, you can exchange your try finally with a using:
try
{
using (var fs = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"/textme.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (var fw = new StreamWriter(fs))
{
fw.Write("sadadasdsadsadsadas");
for (int i = 0; i < AnimalShelter.AnimalList.Count; i++)
{
fw.WriteLine("<chipNr>" + AnimalShelter.AnimalList[i].ChipRegistrationNumber + "<chipNr>");
Console.WriteLine("<chipNr>" + AnimalShelter.AnimalList[i].ChipRegistrationNumber + "<chipNr>");
}
fw.Flush(); // Added
}
}
}
catch(IOException)
{
MessageBox.Show("ERROR THROWN");
}
Enclose your StreamWriter in an using block to be sure that everything is correctly closed at the end of the file usage, also I don't think you need to create a FileStream for this to work.
try
{
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "textme.txt")
using(fw = new StreamWriter(fileName, true))
{
......
}
}
catch(IOException)
{
MessageBox.Show("ERROR THROWN");
}
Note that the StreamWriter has a constructor that accepts two parameters, the name of the file to create/open and a flag to indicate that the file should be opened in append mode or overwritten
See StreamWriter docs
Always use using (as mentioned already) and you won't run into problems (or have to think about it)...
using (FileStream fs = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/textme.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
using (StreamWriter fw = new StreamWriter(fs))
{
fw2.Write("sadadasdsadsadsadas");
}
(also you could have closed the writer instead of filestream which should've worked)
The problem is as I far as I can tell...
FileStream.Close is actually Stream.Close - and that calls Dispose but it ain't virtual, so does some general cleanup.
FileStream.Dispose which is called implicitly when you use using - does specific Flush and then Close/Dispose - so does proper specific cleanup.
You can avoid any of that via using as that is generally recommended pattern (and frankly never got me into any of these)
Indeed, Flush() is the answer; however, I would use File.WriteAllLines() instead.
try
{
var fileName = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"/textme.txt";
var lines = AnimalShelter.AnimalList.Select(o=> "<chipNr>" + o.ChipRegistrationNumber + "</chipNr>");
File.WriteAllLines(fileName, lines);
foreach(var line in lines)
Console.WriteLine(line);
}
catch(IOException)
{
MessageBox.Show("ERROR THROWN");
}
Try using this - just replace the array:
try
{
using (Stream fs = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/textme.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (StreamWriter sw = new StreamWriter(fs))
{
int[] test = new int[] { 0, 12, 23, 46 };
sw.Write("sadadasdsadsadsadas");
for (int i = 0; i < test.Length; i++)
{
sw.WriteLine("<chipNr>" + test[i] + "<chipNr>");
Console.WriteLine("<chipNr>" + test[i] + "<chipNr>");
}
sw.Close();
}
fs.Close();
}
}
catch (IOException)
{
MessageBox.Show("ERROR THROWN");
}

Categories

Resources