Passing data between forms using serialization - c#

Im trying to pass some objects between 2 forms using serialization. It works the first time I use it for each objects, however subsequent attempts don't pass anything over/ when I click the refresh button no new data is loaded into the box.
VirtualAppointments.Add(vir1.ToString());
FileStream outFile;
BinaryFormatter bFormatter = new BinaryFormatter();
//open file
outFile = new FileStream("VirtualAppointments.dat", FileMode.Append, FileAccess.Write);
bFormatter.Serialize(outFile, VirtualAppointments);
outFile.Close();
ViewAppointments viewAppointments = new ViewAppointments();
this.Close();
Im using the above code to pass the write the object to a .dat file and using the next block of code on the second form to read the .dat file into a list box.
private void btnRefresh_Click(object sender, EventArgs e)
{
lstViewAppointments.Items.Clear();
BinaryFormatter bFormater = new BinaryFormatter();
FileStream inFile;
//open file for input
inFile = new FileStream("InPersonAppointments.dat", FileMode.Open, FileAccess.Read);
//obtain object from file via serialization
InPersonAppointmentsForDisplay = (List<String>)bFormater.Deserialize(inFile);
inFile.Close();
foreach(String s in InPersonAppointmentsForDisplay)
{
lstViewAppointments.Items.Add(s);
}
//open file for input
inFile = new FileStream("VirtualAppointments.dat", FileMode.Open, FileAccess.Read);
//obtain object from file via serialization
VirtualAppointmentsForDisplay = (List<String>)bFormater.Deserialize(inFile);
inFile.Close();
foreach (String s in VirtualAppointmentsForDisplay)
{
lstViewAppointments.Items.Add(s);
}
}
As stated above, it works for the first appointment i make for each object, but if i try to make another then when I click the refresh button, it only loads the first item from each serialization file.
Thanks.

Related

Program saying file already in use but i closed it C# [duplicate]

This question already has answers here:
Do I need to dispose the FileStream object?
(3 answers)
Closed 4 years ago.
private void buttonAdd_Click(object sender, EventArgs e)
{
string path = #"comics.txt";
if (!File.Exists(path))
{
var myComicsFile = File.Create(path);
myComicsFile.Close();
FileStream file = new FileStream("comics.txt", FileMode.Open, FileAccess.ReadWrite);
TextWriter write = new StreamWriter(path);
}
else if (File.Exists(path))
{
FileStream file = new FileStream("comics.txt", FileMode.Open, FileAccess.ReadWrite);
TextWriter write = new StreamWriter(path);
}
}
I keep getting the error System.IO.IOException: 'The process cannot access the file because it is being used by another process'
I thought I had fixed it by closing the file after i created it the opening it but i get the error still. Not sure what the correct solution is. Any help would be greatly appreciated.
Firstly, there is no need to create a file empty and open it, instead use the appropriate FileMode Instead
FileMode.OpenOrCreate
OpenOrCreate
Specifies that the operating system should open a file if it exists;
otherwise, a new file should be created. If the file is opened with
FileAccess.Read, Read permission is required. If the file access is
FileAccess.Write, Write permission is required. If the file is opened
with FileAccess.ReadWrite, both Read and Write permissions are
required.
When you use a BCL method always check the documentation for clues about how to use it, in-particular look for if something supports IDisposable if it does ALWAYS use a using statement when you can
using Statement (C# Reference)
Provides a convenient syntax that ensures the correct use of
IDisposable objects.
in short you could have just done this
using (var file = new FileStream("comics.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)
using(var TextWriter write = new StreamWriter(file))
{
// stuff here
}
Basically, when using a using statement with a stream derivative, it closes and disposes any unmanaged resources like file handles. in your case, you have left the File Handle dangling and hence your problem
Use the “using” statement to ensure file is closed.
Reference:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
You can nest using to take away a lot of the potential problems (like you have experienced already) by automatically calling dispose. For example
using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (System.IO.StreamReader sr = new StreamReader(bs))
{
string output = sr.ReadToEnd();
}
}
}

Can't read all lines in file that being used by another process

I am trying to read all lines of log file that being used by some program.
When I tried to do it I am receiving exception:
System.IO.IOException was unhandled : file used by another process
So I searched on the web and found number of solutions:
C# exception. File is being used by another process
Read log file being used by another process
What's the least invasive way to read a locked file in C# (perhaps in unsafe mode)?
C# The process cannot access the file ''' because it is being used by another process
File is being used by another process
http://coding.infoconex.com/post/2009/04/21/How-do-I-open-a-file-that-is-in-use-in-C
The common solutions are to use using to wrap the FileStream and add the FileShare.ReadWrite.
I tried those solutions but I am still receiving the exception that the file is being used by another process.
In my below code I open the file D:\process.log to make the file used (for testing) and then trying to open the file.
The exception is on row:
using (FileStream fileStream = File.Open(i_FileNameAndPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
CODE:
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
DialogResult dialogResult = openFileDialog.ShowDialog();
if (dialogResult == DialogResult.OK)
{
listView.Items.Clear();
File.Open(#"D:\process.log", FileMode.Open); //make the file being used
String fileNameAndPath = openFileDialog.FileName;
String[] fileContent = readAllLines(fileNameAndPath);
}
}
private String[] readAllLines(String i_FileNameAndPath)
{
String[] o_Lines = null;
int i = 0;
using (FileStream fileStream = File.Open(i_FileNameAndPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader streamReader = new StreamReader(fileStream))
{
while (streamReader.Peek() > -1)
{
String line = streamReader.ReadLine();
//o_Lines[i] = line;
i++;
}
}
}
return o_Lines;
}
use an overload of File.Open in your menuclick event handler like this:
File.Open(#"C:\process.log", FileMode.Open,FileAccess.ReadWrite, FileShare.ReadWrite);
The last param is a value specifying the type of access other threads have to the file.
see this article from msdn

FileStream not reading FileName input from external class

I'm trying to make a byte writer. So far I have made the program write the file header as a general test before I continue coding the writer. The problem is, after I select a file through coreForm's coreSaveFileDialog, the line
var fs = new FileStream(classCoreForm.CoreSaveFileDialog.FileName, FileMode.Open, FileAccess.ReadWrite);
doesn't see the FileName from the dialog, and throws an exception saying "Empty path name is not legal."
Here's the source of my method:
internal void writeHeader()
{
var classCoreForm = new coreForm(); //Creates reference instance for coreForm=
var fs = new FileStream(classCoreForm.coreSaveFileDialog.FileName, FileMode.Open, FileAccess.ReadWrite);
/*
* Writes file header via fs.WriteByte . . .
*/
}
writeHeader is being called from a preliminary function called saveScript. Here's its source.
internal void saveScript()
{
var classCoreForm = new coreForm(); //Creates reference instance for coreForm
if (fileAlreadySaved == false)
{
classCoreForm.coreSaveFileDialog.ShowDialog(); //Shows save file dialog
if (classCoreForm.coreSaveFileDialog.FileName != "")
{
writeHeader();
}
else
{
}
}
}
What am I doing wrong? Have I incorrectly set something in the SaveFileDialog's properties, or is it something within the code above?
saveScript() calls writeHeader, but it doesn't pass anything in to writeHeader. You're then creating a completely new instance of "coreForm" which is separate from the instance you created in the saveScript method.
Change writeHeader to accept a file name as an argument:
internal void writeHeader(string fileName)
{
//var classCoreForm = new coreForm(); //Creates reference instance for coreForm=
var fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
/*
* Writes file header via fs.WriteByte . . .
*/
}
Then, in your saveScript() method, change writeHeader(); to
writeHeader(classCoreForm.coreSaveFileDialog.FileName);
If you need the coreForm for other reasons in saveScript, you may want to pass the coreForm by reference, or pass in the other variables you might need into saveScript.

How I can display Stream on the page?

I have a WCF method that I am calling, the method suppose to create a file but it create an exception. I try to find what is in the stream request that I am passing to this method. How I can alert or write this stream so I can find the content. That is my method:
Stream UploadImage(Stream request)
{
Stream requestTest = request;
HttpMultipartParser parser = new HttpMultipartParser(request, "data");
string filePath = "";
string passed = "";
if (parser.Success)
{
// Save the file somewhere
//File.WriteAllBytes(FILE_PATH + title + FILE_EXT, parser.FileContents);
// Save the file
//SaveFile( mtp.Filename, mtp.ContentType, mtp.FileContents);
FileStream fileStream = null;
BinaryWriter writer = null;
try
{
filePath = HttpContext.Current.Server.MapPath("Uploded\\test.jpg"); // BuildFilePath(strFileName, true);
filePath = filePath.Replace("SSGTrnService\\", "");
fileStream = new FileStream(filePath, FileMode.Create);
it produces an error on this line :
fileStream = new FileStream(filePath, FileMode.Create);
that I try to understand why file can not created.
Given the information you gave, I can only assume that your code tries to create the file test.jpg somewhere where your application is not allowed to write. A common mistake would be somewhere in the Program files folder. In modern Windows versions, that is specially protected.

Why is the file not opening?

I can't get the file to open.
private void button1_Click(object sender, EventArgs e)
{
// Load the CSV file
var lines = File.ReadAllLines(#"C:\chat.csv");
var xml = new XElement("Chat-Log", // To convert to XML
lines.Select(line => new XElement("Item",
line.Split('|') // indicate split
.Select((column, index) => new XElement("Column" + index, column)))));
xml.Save(#"C:\xml-out.xml"); // Save to XML file
MessageBox.Show("Converted to XML");
FileStream fileStream = new FileStream(#"c:\xmlout.xml", FileMode.Open);
try
{
TextWriter tw = new StreamWriter("c:\\xml-out.xml");
}
finally
{
fileStream.Close();
}
}
The above piece of code should open C:\xml-out.xml, right?
TextWriter tw = new StreamWriter("c:\\xml-out.xml");
I have no idea why it is not opening the file. Any clue?
I tried various options.
For some reason, you're opening a stream and then trying to create a writer for it.
If the file didn't exist before, then the call to new FileStream(#"c:\xmlout.xml", FileMode.Open) will throw an exception... and if the file did exist before, then you won't be able to open a writer to it in the following line because you've still got the file open for reading. You're also then closing the FileStream in the finally block, but never closing the StreamWriter, which is odd.
I expect you've probably got an exception showing which of those is actually causing the problem, but you should certainly remove the statement for the FileStream.
You should use a using statement so you don't need an explicit try/finally block:
using (StreamWriter writer = File.CreateText(#"c:\xml-out.xml"))
{
}
Of course there's then the possibility that you don't have permission to create a file on the root of the file system...

Categories

Resources