files and binary formatter - c#

I want to ask how to create and write a text file using binary formatter I have written the below code but I have an exception.
the exception is :
file can not been access because it is has been used by another process.
and my code creates two files one is with extension ".txt" and the other without any extension.
what should I do?
Is there another way to create a text file ?
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
namespace ConsoleApplication9
{
[Serializable]
class contact
{
string name;
string address;
string phonenumber;
string emailaddress;
public override string ToString()
{
return name + " " + address + " " + phonenumber + " " + emailaddress;
}
public void AddContent(string cname, string caddress, string cphone, string cemail)
{
name = cname;
address = caddress;
phonenumber = cphone;
emailaddress = cemail;
FileStream file = new FileStream("contact.txt", FileMode.OpenOrCreate, FileAccess.Write);
BinaryFormatter bin = new BinaryFormatter();
contact person = new contact();
person.name = cname;
person.address = caddress;
person.phonenumber = cphone;
person.emailaddress = cemail;
bin.Serialize(file, person);
file.Close();
Console.WriteLine(" added sucefully");
}//end of fun add
}

Your exception has nothing to do with the BinaryFormatter but instead with the fact that you are not disposing of the FileStream properly. Always wrap streams in a using block:
using(FileStream file = new FileStream("contact.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
//code here
}
This guarantees that the stream underneath is closed and the unmanaged resources are freed. In your case in particular, it seems that the OS still has a lock to the file you are attempting to create and the second time you run your code throws the exception about your file being used by another process

file can not been access because it is has been used by another process.
Is it possible that you may have in advertantly opened this file and its still open in a text window?

Related

zip a file programatically like native send to compressed zip folder

I have to send a zipped file to an external application. Support on the other end says the application fails to read my programatically created file. This is how i create the file:
using System.IO;
using System.IO.Compression;
const string ZIPPATH = #".\stock.zip";
const string PACKAGEPATH = #".\stock\content";
const string APPPACKAGE = #".\stock";
const string PACKAGEFILENAME = #"content\Offers.xml";
private void CreateZipArchive()
{
if (!Directory.Exists(PACKAGEPATH)) Directory.CreateDirectory(PACKAGEPATH);
if (File.Exists(ZIPPATH)) File.Delete(ZIPPATH);
ZipFile.CreateFromDirectory(APPPACKAGE, ZIPPATH);
using (FileStream fs = new FileStream(ZIPPATH, FileMode.Open))
using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Update))
{
ZipArchiveEntry zae = archive.CreateEntry(PACKAGEFILENAME);
using (StreamWriter sw = new StreamWriter(zae.Open(), new UTF8Encoding(true)))
{
// xml writing code ...
sw.Write("--snipped--");
}
}
}
the folder APPPACKAGE contains some required files. After zip creation I insert my created xml file. inspecting the contents of the created zip file everything looks right yet the recipient application fails to read it. My question is: Is there something I might have missed?
Edit: Client gave me little additional Feedback. The only thing mentioned was that filure to read the package can happen if there is an md5 error. I suspect now that it could be related to the order in which I create the package. I'll try to first create the xml file and then create the zip file
Although LukaszSzczygielek pointed out another possible Issue in zip file creation the solution of my particular problem is to first create the files and then create the package:
using System.IO;
using System.IO.Compression;
const string ZIPPATH = #".\stock.zip";
const string PACKAGEPATH = #".\stock\content";
const string APPPACKAGE = #".\stock";
const string PACKAGEFILENAME = #"\Offers.xml";
private void CreateZipArchive()
{
if (!Directory.Exists(PACKAGEPATH)) Directory.CreateDirectory(PACKAGEPATH);
if (File.Exists(ZIPPATH)) File.Delete(ZIPPATH);
string fileFullPath = PACKAGEPATH + PACKAGEFILENAME;
using(Stream fs = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write))
using(StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(true)))
{
// xml writing code ...
sw.Write("--snipped--");
}
ZipFile.CreateFromDirectory(APPPACKAGE, ZIPPATH);
}

Why doesn't FileStream as an argument to Streamwriter write to text file?

In the code included below, I am able to write the contents of the string 'fullname' to a text file in the specified directory when using the following statement:
System.IO.File.WriteAllText(path, fullname);
However, if I write the string path to a FileStream object (withe arguments specified), and then pass that FileStream object as an argument to the StreamWriter object, the file is created, but no contents are written.
First attempt: Comment out System.IO.File.WriteAllText(path, fullname); and use the three lines above it. This creates the file but no contents are written into the file.
Second attempt: Un-comment the System.IO.File.WriteAllText(path, fullname); statement and comment the three lines above it. This executes as desired.
Here is the full block of code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace FileInputOutput
{
class Program
{
static void Main(string[] args)
{
// Use the Split() method of the String Class
string fullname = " Robert Gordon Orr ";
fullname = fullname.Trim();
string[] splitNameArray = fullname.Split(' ');
Console.WriteLine("First Name is: {0}", splitNameArray[0]);
Console.WriteLine("Middle Name is: {0}", splitNameArray[1]);
Console.WriteLine("Last Name is: {0}", splitNameArray[2]);
Console.WriteLine("Full name is: {0}", fullname);
string path = #"C:\Programming\C#\C# Practice Folder\Console Applications\FileInputOutput\textfile.txt";
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);
StreamWriter toFile = new StreamWriter(fs);
toFile.Write(fullname);
//System.IO.File.WriteAllText(path, fullname);`enter code here`
Console.ReadLine();
}
}
}
As others have said: streams must be flushed in .NET in order for them to write to disk. This can be done manually, however I would simply change your code to have using statements on your streams:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace FileInputOutput
{
class Program
{
static void Main(string[] args)
{
// Use the Split() method of the String Class
string fullname = " Robert Gordon Orr ";
fullname = fullname.Trim();
string[] splitNameArray = fullname.Split(' ');
Console.WriteLine("First Name is: {0}", splitNameArray[0]);
Console.WriteLine("Middle Name is: {0}", splitNameArray[1]);
Console.WriteLine("Last Name is: {0}", splitNameArray[2]);
Console.WriteLine("Full name is: {0}", fullname);
string path = #"C:\textfile.txt";
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
{
using (StreamWriter toFile = new StreamWriter(fs))
{
toFile.Write(fullname);
}
}
//System.IO.File.WriteAllText(path, fullname);`enter code here`
Console.ReadLine();
}
}
}
Calling Dispose() on a stream (as using implicitly does), causes the stream to be flushed and closed at the end of the using block.
I think you are just forgetting to flush your file stream:
fs.Flush();
This is needed because according to msdn, this is what makes the FileStream to actually write the buffer to the file.
Flush: Clears buffers for this stream and causes any buffered data to be written to the file. (Overrides Stream.Flush().)
Regards.
From MSDN on StreamWriter
You must call Close to ensure that all data is correctly written out to the underlying stream.
So the problem here is mainly that, since you don't actually close the StreamWriter, the data gets backed up but doesn't push to the file, even though the FileStream immediately created the file in its constructor. Never ever forget to close your stream, as failing to do so could lead to major problems down the line.

How to copy a pst file while it is open using c# [duplicate]

This question already has answers here:
How to copy a file while it is being used by another process
(7 answers)
Closed 9 years ago.
Is it possible to copy a pst file using c# with outlook open?
Here is the code i have got already but it still gives me the error :The process cannot access the file 'filepath' because it is being used by another process.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace outlookPSTCopy
{
class Program
{
static void Main(string[] args)
{
string done = "the file is done copying";//done massage
string copyFrom = args[0];
string copyTo = args[1];
Console.WriteLine(copyTo);
Console.ReadLine();
try
{
//start of test
using (var inputFile = File.Open(copyFrom, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
using (var outputFile = new FileStream(copyTo, FileMode.Create))
{
var buffer = new byte[0x10000];
int bytes;
while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0)
{
outputFile.Write(buffer, 0, bytes);
}
}
}
//end of test
//System.IO.File.Copy(copyFrom, copyTo, true);
}
catch (Exception copyError)
{
Console.WriteLine("{0} Second exception caught.", copyError);
}
Console.WriteLine("{0} ", done);
Console.ReadLine();
}
}
}
Thank you for your help!
To create a copy of a file that is locked by another process on Windows, the simplest (and probably only) solution is to use the Volume Shadow Copy Service (VSS).
The Volume Shadow Copy Service is complex and difficult to call from managed code. Fortunately, some fine chaps have created a .NET class library for doing just this. Check out the Alpha VSS project on CodePlex: http://alphavss.codeplex.com.

File is being used by another process except that it's not

I'm currently working on a utility to parse multiple xml files and write the results to a csv file. On the second last line(of code) I get the error:
The process cannot access the file 'W:\SRC\hDefML\myExcelFile.csv' because it is being used by another process.'.
Can someone please help me because I have no idea what's wrong, the file isn't being used by anything else and it's driving me crazy?
Here is my code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace GenNameUtility
{
class NameGenerator
{
static void Main(string[] args)
{
var files = from file in Directory.GetFiles("W:\\SRC\\hDefMl\\1.0\\Instrument_Files") orderby file
ascending select file;
StringBuilder sb_report = new StringBuilder();
string delimiter = ",";
sb_report.AppendLine(string.Join(delimiter, "Module", "Generator(s)"));
foreach (var file in files)
{
string filename = Path.GetFileNameWithoutExtension(file);
Console.Write("The HDefML file for {0} contains these EEPROM Generators:", filename);
XDocument hdefml = XDocument.Load(file);
var GeneratorNames = from b in hdefml.Descendants("Generators") select new
{
name = (string)b.Element("GeneratorName")
}.ToString();
StringBuilder sb = new StringBuilder();
foreach (var item in GeneratorNames)
{
Console.Write(" GeneratorName is: {0}", GeneratorNames);
sb_report.AppendLine(string.Join(delimiter, filename, GeneratorNames));
var hdef = File.Create(#"W:\SRC\hDefML\myExcelFile.csv").ToString();
File.WriteAllText(hdef, sb.ToString());
}
}
Console.ReadLine();
}
}
}
You need to close the file after you have written to it. See using.
Also it would be better to open the file before the loop and close it thereafter.
The file is being used by another process... but the process is actually yours.
File.Create returns a FileStream. You're opening the file.. writing to it.. but not closing it. When the new iteration comes around.. the file is still open.
You can try something like this:
using (var file = File.Create(#"W:\SRC\hDefML\myExcelFile.csv")) {
// write content here using file
} // this closes the file automatically.
As suggested though, I would wrap the above outside of the loop, so you're not constantly opening and closing the file.
File.WriteAllText will create a file for you so there's no need to use File.Create beforehand.
File.WriteAllText(#"W:\SRC\hDefML\myExcelFile.csv", sb.ToString());
Your File.Create stream seems to be holding the lock on the file which is why File.WriteAllText is throwing the error.
If you need to use File.Create you can use a StreamWriter to write it out.
using(var fs = File.Create(#"W:\SRC\hDefML\myExcelFile.csv"))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(sb.ToString());
}
as a side note, the above using format is the same as doing
using(var fs = File.Create(#"W:\SRC\hDefML\myExcelFile.csv"))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(sb.ToString());
}
}
so you can use whichever you find more readable.

Creating a new .txt file with date in front, C#

I am trying to get the following: [today's date]___[textfilename].txt from the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication29
{
class Program
{
static void Main(string[] args)
{
WriteToFile();
}
static void WriteToFile()
{
StreamWriter sw;
sw = File.CreateText("c:\\testtext.txt");
sw.WriteLine("this is just a test");
sw.Close();
Console.WriteLine("File created successfully");
}
}
}
I tried putting in DateTime.Now.ToString() but i cannot combine the strings.
Can anybody help me? I want the date in FRONT of the title of the new text file I am creating.
static void WriteToFile(string directory, string name)
{
string filename = String.Format("{0:yyyy-MM-dd}__{1}", DateTime.Now, name);
string path = Path.Combine(directory, filename);
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("This is just a test");
}
}
To call:
WriteToFile(#"C:\mydirectory", "myfilename");
Note a few things:
Specify the date with a custom format string, and avoid using characters illegal in NTFS.
Prefix strings containing paths with the '#' string literal marker, so you don''t have to escape the backslashes in the path.
Combine path parts with Path.Combine(), and avoid mucking around with path separators.
Use a using block when creating the StreamWriter; exiting the block will dispose the
StreamWriter, and close the file for you automatically.
You'd want to do a custom string format on DateTime.Now. You can use String.Format() to combine the results of that with your base filename.
To append on the path to the filename, use Path.Combine().
Finally, use a using() block to properly close & dispose your StreamWriter when you are finished with it...
string myFileName = String.Format("{0}__{1}", DateTime.Now.ToString("yyyyMMddhhnnss"), "MyFileName");
strign myFullPath = Path.Combine("C:\\Documents and Settings\\bob.jones\\Desktop", myFileName)
using (StreamWriter sw = File.CreateText(myFullPath))
{
sw.WriteLine("this is just a test");
}
Console.WriteLine("File created successfully");
Edit: fixed sample to account for path of "C:\Documents and Settings\bob.jones\Desktop"
Try this:
string fileTitle = "testtext.txt";
string fileDirectory = "C:\\Documents and Settings\username\My Documents\";
File.CreateText(fileDirectory + DateTime.Now.ToString("ddMMYYYY") + fileTitle);
?
To answer the question in your comment on #Scott Ivey's answer:
to specify where the file is written to, prepend the desired path to the file name before or in the call to CreateText().
For example:
String path = new String (#"C:\Documents and Settings\bob.jones\Desktop\");
StreamWriter sw = File.CreateText(path + myFileName);
or
String fullFilePath = new String (#"C:\Documents and Settings\bob.jones\Desktop\");
fullFilePath += myFileName;
StreamWriter sw = File.CreateText(fullFilePath);

Categories

Resources