Dear all,
I'm relatively new to C# and have a problem that stumps me. I think it might be related to something called an 'assembly'. I store and retrieve data to/from file 'serializing' two ArrayLists ('BinaryFormatter') and also store two plain integers using 'BinaryWriter'. See code functions "LoadFromFile()" and "StoreToFile()".
The program works just fine until I try to run it in another directory.
That is to say I copied and compiled all the source files into the new directory. I then also copied the datafile ("videostore.bin") created by the identical same program in the old directory and expected it to work just the same in the new directory, why shouldn't it, right ?
I get this error message (just the head, it's a lot longer).
//
System.IO.FileNotFoundException: Could not load file or assembly 'Videostore' or one of its dependencies. The system cannot find the file specified.
File name: 'Videostore'
//
The exception occurs on the first Deserialize statement.
Videos = (ArrayList) bf.Deserialize (stream);
It finds the file. That is not the problem. If I remove the file then it hits 'Exception' on the previous line "stream = File.Open (..." as it should. Further If I comment out (remove) the two Deserialize statements then it will not make 'Exception' but instead read two integers (which gets nonsense values now of course).
If I use "StoreToFile()" to create a new datafile in the new directory (instead of using the identical datafile copied from the old directory) and then tries "LoadFromFile()" anew, then it will work. It is as if it refuses to load an identical file if it hasn't written it itself. Bizarre ...
It must be some kind of contextual information is written somewhere when the file is created by "StoreToFile()". But it only needs this for more complex file operations like 'Serialize', the simpler read/write of integers works without throwing exceptions.
I suspect I need to supply additional info, perhaps in the form of an 'assembly' file for it to work.
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
class filedebug
{
public ArrayList Videos;
public ArrayList Customers;
int a=0, b=0;
static void Main ()
{
(new filedebug ()).Run ();
}
void Run()
{
Console.WriteLine( LoadFromFile ());
Console.WriteLine( StoreToFile ());
}
public bool LoadFromFile ()
{
bool success = true;
FileStream stream = null;
BinaryFormatter bf = new BinaryFormatter ();
try
{
stream = File.Open ("videostore.bin", FileMode.Open, FileAccess.Read);
Videos = (ArrayList) bf.Deserialize (stream);
Customers = (ArrayList) bf.Deserialize (stream);
using (BinaryReader br = new BinaryReader(stream))
{
a = br.ReadInt32();
b = br.ReadInt32();
}
}
catch (Exception e)
{
Console.WriteLine(e);
success = false;
}
finally
{
if (stream != null)
stream.Close ();
}
return success;
}
public bool StoreToFile ()
{
bool success = true;
FileStream stream = null;
BinaryFormatter bf = new BinaryFormatter ();
try
{
stream = File.Open ("videostore.bin", FileMode.Create, FileAccess.Write);
bf.Serialize (stream, Videos);
bf.Serialize (stream, Customers);
using (BinaryWriter bw = new BinaryWriter(stream))
{
bw.Write (a);
bw.Write (b);
}
}
catch (Exception)
{
success = false;
}
finally
{
if (stream != null)
stream.Close ();
}
return success;
}
}
Loading
pagefault pagefaultPosted Mar 14, 2012, 1:55 PM
This is handled by the exception. The file not existing is not neccesarily considered an error. It just means that there is no data yet. Data is input to the application and written to file on exit.
I found a way to make it work. But it is still bizarre. It works if the filename of the exe is the same as the namespace / project name for some reason. The project is named 'Videostore'. The namespace is named 'Videostore'. And one of the files (the core program) is named 'Videostore.cs'
The project has multiple files, one for each class, like this:
Actor.cs
videostore.bin
Customer.cs
VideostoreConsole.cs
Videostore.exe
Video.cs
Videostore.cs
VideostoreUI.cs
I use the Monodevelop (LINUX) enviroment. And in there it worked just fine. The project/namespace name is 'Videostore'. The exe file gets named 'Videostore.exe' I just noticed.
Previously I copied all the source files to another location and command line compiled them (still using Mono), like this
gmcs VideostoreConsole.cs Videostore.cs Actor.cs Customer.cs Video.cs VideostoreUI.cs -r:System.Windows.Forms.dll -r:System.Drawing.dll
Putting the VideostoreConsole.cs first because thats where the Main function resides. And the exe file became named VideostoreConsole.exe. And this didn't work.
Just switching order and putting 'Videostore.cs' so the name of the exe becomes 'Videostore.exe' instead just like inside the IDE enviroment, like this:
gmcs Videostore.cs VideostoreConsole.cs Actor.cs Customer.cs Video.cs VideostoreUI.cs -r:System.Windows.Forms.dll -r:System.Drawing.dll
... and now it works. Bizarre. Why would the name of the exe file matter ?
I got inspired to try the latest after having just copied the exe ('Videostore.exe') and the datafile ('videostore.bin') from inside the enviroment directory to another directory, running it and to my surprise see that it worked. For some reason the name of the exe matters. I'm sure there is a reason and one fine day the coin will drop.
SenthilkumarPosted Mar 14, 2012, 10:42 AM
It seems there is no issue with the code. When you give the file name alone in the file path option then it will search in the current directory. The exe of the code and videostore.bin should be in the same folder.
But i would recommend you to always check the file is exists or not.
If(File.Exists(@"c:\Test\test.txt"))
{
//Write the logic to read or write into the file.
}
else
{
File.Create(@"c:\Test\test.txt");
}
If it helps you to solve this issue then mark it as "Accepted Answer"