How to override a specific line in a text file in c# - c#

I have the following situation. I am creating a quiz game in c# visual studio and want to create a Register and Login forms. When a user registers a new account the text file will store their username and password and will set the high score to 0. Each line in the text file looks like that: username;password;highscore. ';' is the delimiter. I have created a new project to create a practice login/ register form. Here is my code for the register form:
private void btnRegister_Click(object sender, EventArgs e)
{
if (txtPassword.Text == txtConfirmPassword.Text)
{
string newAccount = txtName.Text + ";" + txtConfirmPassword.Text + ";" + "0";
TextWriter account = new StreamWriter("../../TextFile/LogonDetails.txt", true);
account.WriteLine(newAccount);
account.Close();
MessageBox.Show("Account created");
}
and here is my code for the login form
string line = "";
StreamReader myReader = new StreamReader("../../TextFile/LogonDetails.txt");
string[] accounts = new string[900000]; int value = 0;
while ((line=myReader.ReadLine()) != null)
{
string[] data = line.Split(';');
if ((data[0] == txtLoginName.Text) && (data[1] == txtLoginPassword.Text) && (int.Parse(data[2]) > int.Parse(txtScore.Text)))
{
value = 1;
break;
}
if ((data[0] == txtLoginName.Text) && (data[1] == txtLoginPassword.Text) && (int.Parse(data[2]) < int.Parse(txtScore.Text)))
{
value = 2;
break;
}
else
{
value = 3;
}
}
if (value == 1)
{
MessageBox.Show("Your score remains the same");
}
else if (value == 2)
{
string updatedAccount = txtLoginName.Text + ";" + txtLoginPassword.Text + ";" + txtScore;
TextWriter textAccounts = new StreamWriter("../../TextFile/LogonDetails.txt");
textAccounts.WriteLine(updatedAccount);
textAccounts.Close();
}
else if (value == 3)
{
MessageBox.Show("Account not found");
}
}
So my question is how can I override the line stored in the text file if in this case 'txtScore' is greater than data[2]? I have tried creating a new line each time the score is greater but that seems inefficient. Is there a way that i can override the line to change the score value? Any help is greatly appreciated

If the file is not that long you can do something like this:
String fileName = #"C:\LogonDetails.txt";
var data = File
.ReadLines(fileName)
.Select(line => line.Split(';'))
.Select(items => {
if ((items[0] == txtLoginName.Text) &&
(items[1] == txtLoginName.Text) &&
(int.Parse(items[2]) < int.Parse(txtScore.Text)))
items[2] = int.Parse(txtScore.Text);
return items;
})
.ToList(); // materialize in oreder to prevent file read/write collision
File.WriteAllLines(fileName, data);

There is no straightforward way to target a specific line in a text file to update the contents on that line. I would suggest storing your information in an XML (structured data) format; .NET already has the capabilities built in for reading and writing to specific nodes in an XML file.
If you don't want to do that, then my suggestion would be that you load all the lines from the text file into memory as instances of, e.g. a User class that has as properties your username, password, and score, and then write them all back out to your data file all at once with any updates to the scores.
By the way, it's generally not a good idea to store passwords in plain text, so I would hope you're at least employing a hashing algorithm.

Well, based on your question you know the line number, so do something like this:
var lines = File.ReadAllLines(#"path to file");
if (lines.Contains("1234"))
{
lines[Array.IndexOf(lines, "1234")] = "new york";
}
File.WriteAllLines(#"path to file", lines);
try like this.

Related

Convert PDF to TIFF using ImageMagick & C#

I have an existing program that does some processing a .pdf file and splitting it into multiple .pdf files based on looking for barcodes on the pages.
The program uses ImageMagick and C#.
I want to change it from outputting pdfs to outputting tifs. Look for the comment in the code below for where I would guess the change would be made.
I included the ImageMagick tag because someone might offer a commandline option that someone else can help me convert to C#.
private void BurstPdf(string bigPdfName, string targetfolder)
{
bool outputPdf = true; // change to false to output tif.
string outputExtension = "";
var settings = new MagickReadSettings { Density = new Density(200) };
string barcodePng = Path.Combine("C:\TEMP", "tmp.png");
using (MagickImageCollection pdfPageCollection = new MagickImageCollection())
{
pdfPageCollection.Read(bigPdfName, settings);
int inputPageCount = 0;
int outputPageCount = 0;
int outputFileCount = 0;
MagickImageCollection resultCollection = new MagickImageCollection();
string barcode = "";
string resultName = "";
IBarcodeReader reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>();
reader.Options.PossibleFormats.Add(BarcodeFormat.CODE_39);
reader.Options.TryHarder = false;
foreach (MagickImage pdfPage in pdfPageCollection)
{
MagickGeometry barcodeArea = getBarCodeArea(pdfPage);
IMagickImage barcodeImg = pdfPage.Clone();
barcodeImg.ColorType = ColorType.Bilevel;
barcodeImg.Depth = 1;
barcodeImg.Alpha(AlphaOption.Off);
barcodeImg.Crop(barcodeArea);
barcodeImg.Write(barcodePng);
inputPageCount++;
using (var barcodeBitmap = new Bitmap(barcodePng))
{
var result = reader.Decode(barcodeBitmap);
if (result != null)
{
// found a first page because it has bar code.
if (result.BarcodeFormat.ToString() == "CODE_39")
{
if (outputFileCount != 0)
{
// write out previous pages.
if (outputPdf) {
outputExtension = ".pdf";
} else {
// What do I put here to output a g4 compressed tif?
outputExtension = ".tif";
}
resultName = string.Format("{0:D4}", outputFileCount) + "-" + outputPageCount.ToString() + "-" + barcode + outputExtension;
resultCollection.Write(Path.Combine(targetfolder, resultName));
resultCollection = new MagickImageCollection();
}
barcode = standardizePhysicalBarCode(result.Text);
outputFileCount++;
resultCollection.Add(pdfPage);
outputPageCount = 1;
}
else
{
Console.WriteLine("WARNING barcode is not of type CODE_39 so something is wrong. check page " + inputPageCount + " of " + bigPdfName);
if (inputPageCount == 1)
{
throw new Exception("barcode not found on page 1. see " + barcodePng);
}
resultCollection.Add(pdfPage);
outputPageCount++;
}
}
else
{
if (inputPageCount == 1)
{
throw new Exception("barcode not found on page 1. see " + barcodePng);
}
resultCollection.Add(pdfPage);
outputPageCount++;
}
}
if (File.Exists(barcodePng))
{
File.Delete(barcodePng);
}
}
if (resultCollection.Count > 0)
{
if (outputPdf) {
outputExtension = ".pdf";
} else {
// What do I put here to output a g4 compressed tif?
outputExtension = ".tif";
}
resultName = string.Format("{0:D4}", outputFileCount) + "-" + outputPageCount.ToString() + "-" + barcode + outputExtension;
resultCollection.Write(Path.Combine(targetfolder, resultName));
outputFileCount++;
}
}
}
[EDIT] The above code is what I am using (which some untested modifications) to split a .pdf into other .pdfs. I want to know how to modify this code to output tiffs. I put a comment in the code where I think the change would go.
[EDIT] So encouraged by #fmw42 I just ran the code with the .tif extension enabled. Looks like it did convert to a .tif, but the tif is not compressed. I am surprised that IM just configures the output based on the extension name of the file. Handy I guess, but just seems a little loose.
[EDIT] I figured it out. Although counter-intuitive ones sets the compression on the read of the file. I am reading a .pdf but I set the compression to Group for like this:
var settings = new MagickReadSettings { Density = new Density(200), Compression = CompressionMethod.Group4 };
The thing I learned was that simply naming the output file .tif tells IM to output a tif. That is a handy way to do it, but it just seems sloppy.

C# Best way to create folder-structures

I'd like to automatically generate diffrent folder structures (As a preperation for new Video/Film-Editing projects). It also allows to add special folders like After Effects and Photoshop to every folder-structure.
It should read the structure from a config file and then create the folders.
My current code looks like this:
if(tbPath.Text == "_______________________________________________________"
|| tbConfigPath.Text == "_______________________________________________________"
|| tbPath.Text == ""
|| tbConfigPath.Text == "")
{
System.Windows.MessageBox.Show("You didn't enter a valid Path.", "Invalid Path", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
//List for the paths
List<string> paths = new List<string>();
List<string> finalpaths = new List<string>();
string outPath = tbPath.Text;
//Where to get the config from
string configPath = tbConfigPath.Text;
string line = "";
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader(configPath);
while ((line = file.ReadLine()) != null)
{
paths.Add(line);
}
file.Close();
for (int i = 0; i < paths.Count(); i++)
{
finalpaths.Add(outPath + paths[i]);
}
//----------------Folder Generatring------------
for (int i = 0; i < paths.Count(); i++)
{
Directory.CreateDirectory(finalpaths[i]);
}
// Add After Effects
if (cbAE.IsChecked == true)
{
string AEpath = outPath + "\\AfterEffects";
Directory.CreateDirectory(AEpath);
}
// Add Photoshop
if (cbAE.IsChecked == true)
{
string PSpath = outPath + "\\Photoshop";
Directory.CreateDirectory(PSpath);
}
System.Windows.MessageBox.Show("The folders where generated successfully", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
pgStartUp pgStart = new pgStartUp();
NavigationService.Navigate(pgStart);
But I feel like this isn't really efficient. Is there any better way?
When you use:
Directory.CreateDirectory(path);
This line creates all or missing directories in the path string you are passing as a parameter. So you don't need anything else.
All your logic should be focused on creating a correct path string, taking into account the root directory and things like that.
As coders we often think in code and try to solve everything with it.
If the base structure is the same, create the folder structure once, zip it up, and then:
Directory.CreateDirectory(tbPath.Text);
ZipFile.ExtractToDirectory("yadayada.zip", tbPath.Text);
// Add After Effects
if (cbAE.IsChecked == true)
{
string AEpath = outPath + "\\AfterEffects";
Directory.CreateDirectory(AEpath);
}
// Add Photoshop
if (cbAE.IsChecked == true)
{
string PSpath = outPath + "\\Photoshop";
Directory.CreateDirectory(PSpath);
}

How to delete all lines in text file that is NOT a number greater than a specific value? (Including strings)

My Issue:
I am looking into a text file and i need to delete all the lines, or use string.empty that does not meet the requirement. For example,
The requirement is 50000. There are words/text in the file and also numbers that are smaller than the requirement. How can i delete all line in a text file that do not meet the requirement? I do not want to be specific with the other values in the text file as they can differ.
My Research:
I have searched and found to delete specific values then rewrite them onto a new file which i am trying to do. I have found different ways that dont meet my needs. I am using what i have found below but am missing something to make it complete
My Effort:
DialogResult openFile = openFileDialog1.ShowDialog();
if (openFile == DialogResult.OK)
{
string file = openFileDialog1.FileName;
string content = File.ReadAllText(file);
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Text File|*.txt";
sfd.FileName = "New Text Doucment";
sfd.Title = "Save As Text File";
if (sfd.ShowDialog() == DialogResult.OK)
{
string path = sfd.FileName;
StreamWriter bw = new StreamWriter(File.Create(path));
bw.WriteLine(content);
bw.Close();
File.WriteAllLines(path, File.ReadAllLines(path).Select(x => string.Format("{0},", x)));
string newContent = File.ReadAllText(path);
newContent = newContent.Remove(newContent.LastIndexOf(","));
File.WriteAllText(path, newContent);
string secondContent = File.ReadAllText(path);
int number = int.Parse(File.ReadAllText(path));
if (checkBox1.Checked == true)
{
secondContent = secondContent.Replace("BRUSH(1,0)", string.Empty);
secondContent = secondContent.Replace("REGION 1,", string.Empty);
secondContent = secondContent.Remove(secondContent.LastIndexOf(","));
File.WriteAllText(path, secondContent);
if (secondContent.Contains())
{
number = 0;
secondContent = secondContent.Replace(number.ToString(), string.Empty);
File.WriteAllText(path, secondContent);
}
}
else if (checkBox2.Checked == true)
{
secondContent = secondContent.Replace("BRUSH(1,0),", ")),");
secondContent = secondContent.Replace("REGION 1,", string.Empty);
secondContent = secondContent.Remove(secondContent.LastIndexOf(","));
File.WriteAllText(path, secondContent);
}
//Just trying
foreach (char c in secondContent)
{
if (secondContent.All(char.IsDigit))
{
char = string.Empty;
}
}
}
}
What i am doing above:
Grabbing an existing file,
adding the contents to a new file,
add a comma at the end of each line,
removing the last comma at the end of the file.
removing a line that contains brush or region
Now here are examples of the file:
TYPE_CODE char(2),
DESCRIPT0 char(25),
TYPE_COD0 char(3),
DESCRIPT1 char(36),
DATA,
BRUSH(1,0),
REGION(1,0),
13502,
319621.99946835 110837.002493295,
319640.501385461 110850.59860145,
319695.199120806 110879.700271183,
319728.303041127 110879.300385649,
319752.898058391 110876.501186912,
319767.401120868 110872.702274339,
The numbers at the bottom of that example is what the entire document should look like
To address just the issue stated try the following:
//Get the lines from the file
List<string> lines = System.IO.File.ReadAllLines("MyFile.txt").ToList();
//Removed the lines which are empty or when split using ' ' contain items other the numbers >= 50000
double d = 0;
lines.RemoveAll(x => string.IsNullOrWhiteSpace(x) || x.TrimEnd(',').Split(' ').Any(y => !double.TryParse(y, out d) || double.Parse(y) < 50000));
//Write the new file
System.IO.File.WriteAllLines("MyFile2.txt", lines.ToArray());
To add a comma to the end of each line add the following lines before saving:
//Remove any existing ',' and add our own
lines = lines.Select(x => x.TrimEnd(',') + ",").ToList();
//Remove any trailing ',' from the last line
lines[lines.Count - 1] = lines[lines.Count - 1].TrimEnd(',');
(Edited to handle multiple numbers per line)
(Fixed conversion errors)
(Fixed for existing ',')
First, abstraction would be your friend here. Break up your code into different peices to make it a little easier to handle. Plus when you have to change your requirements later, you will have an easy spot to do it.
Second, File.ReadLines is also your friend because it will give you a collection of strings, which will let you use LINQ.
Which brings me to your third friend, LINQ, which will let you query the collection of file lines.
public void FormatFile(string sourcePath, string targetPath)
{
IEnumerable<String> originalContent = GetFileLines(sourcePath);
IEnumerable<String> formatedContent = ProcessFileLines(originalContent);
OutputResults(targetPath, formatedContent);
}
public IEnumerable<String> GetFileLines(string path) {
return File.ReadLines(path);
}
public IEnumerable<string> ProcessFileLines(IEnumerable<string> fileLines)
{
// In this method you can process the logic that applies to the whole
// set of file lines (e.g. lineCount, removing empyLines, etc)
return processedLines.Select(l => ProcessLine(l)
.Where(l => !string.IsNullOrEmpty(l))
.GetRange(0, MAX_LINE_COUNT);
}
public string ProcessLine(string fileLine)
{
// In this method just focus on logic applied to each specific line.
string s = fileLine.Substring(0, 5);
if (s.Equals("BRUSH", StringComparison.InvariantCultureIgnoreCase)
return string.Empty;
return fileLine;
}
public void OutputResults(string targetPath, IEnumerable<string> fileLines)
{
string outputText = fileLines.Join($",{Environment.NewLine}");
File.WriteAllText(targetPath, outputText);
}
So basically you can just call FormatFile(#"C:\mySource", #"C:\myTarget"); and you will be good to go.

How to read and update multiple files

I have 10 txt files in Debug\Tests\Text\ (10 txt files). I need to write a program to open all 10 files and updated every single file. I'm not sure how to do it. Now, I'm actually reading the folder and getting the file name and storing the file name in an array. Below is my code:
private void getFilesName()
{
string[] fileArray = Directory.GetFiles(#"Tests\Text");
//looping through the folder and get the fileNames
for (int i = 0; i<fileArray.Length; i++)
{
MessageBox.Show(fileArray[i]); // I'm doing this is to double check i manage to get the file name.
}
}
After doing this, it do read all the text file name, but the challenge now is for me to access the filename and updating every file in it. I have also created another method just for updating the values in the txt files, below is the code:
private bool modifySQLFile()
{
string destFileName = #"Tests\Text\" // I need the fileName?
string[] fileTexts = File.ReadAllLines(destFileName);
int counter = 0;
//Processing the File
foreach(string line in fileTexts)
{
//only read those non-comments line
if(line.StartsWith("--") == false)
{
//Start to replace instances of Access ID
if(line.Contains(Variable) == true)
{
fileTexts[counter] = fileTexts[counter].Replace(Variable, textBox2.Text);
}
}
counter++;
}
//check if file exists in the backup folder
if(File.Exists("Tests\\Text\\file name "+ textBox1.Text +".sql") == true)
{
MessageBox.Show("This file already exist in the backup folder");
return false;
}
else
{
//update the file
File.WriteAllLines(destFileName, fileTexts);
File.Move(destFileName, "Tests\\Text\\file name"+ textBox1.Text +".sql");
MessageBox.Show("Completed");
return true;
}
}
Your problem seems to be passing the filename variable from the loop to the method.
In order to do what you want, add a parameter to the method:
private bool ModifySQLFile(string filename)
{
string[] fileTexts = File.ReadAllLines(filename);
// ...
}
Then call the method with this parameter:
for (int i = 0; i<fileArray.Length; i++)
{
ModifySQLFile(fileArray[i]);
}
But in general you really don't want to treat a formal language as plaintext like you do. It's very easy to break the SQL like that. What if the user wanted to replace the text "insert", or replaces something with "foo'bar"?
First, implement one (file) modification:
private bool modifySQLFile(String file) {
// given source file, let´s elaborate target file name
String targetFile = Path.Combine(
Path.GetDirectoryName(file),
String.Format("{0}{1}.sql",
Path.GetFileNameWithoutExtension(file),
textBox1.Text));
// In case you want a back up
//TODO: given source file name, elaborate back up file name
//String backUpFile = Path.Combine(...);
// Check (validate) before processing: do not override existing files
if (File.Exists(targetFile))
return false;
//TODO: what if back up file exists? Should we override it? skip?
// if line doesn't start with SQL commentary --
// and contains a variable, substitute the variable with its value
var target = File
.ReadLines(file)
.Select(line => (!line.StartsWith("--") && line.Contains(Variable))
? line.Replace(Variable, textBox2.Text)
: line);
// write modified above lines into file
File.WriteAllLines(targetFile, target);
// In case you want a back up
// Move file to backup
//File.Move(file, backUpFile);
return true;
}
Then call it in the loop:
// enumerate all the text files in the directory
var files = Directory
.EnumerateFiles("#"Tests\Text", "*.txt");
//TODO: you may want filter out some files with .Where
//.Where(file => ...);
// update all the files found above
foreach (var file in files) {
if (!modifySQLFile(file))
MessageBox.Show(String.Format("{0} already exist in the backup folder", file));
}
Please, do not do:
Use Magic values: what is #"Tests\Text\" within your modifySQLFile
Mix UI MessageBox.Show(...) and logic: modifySQLFile returns true or false and it's caller who can display message box.
Materialize when it's not required (Directory.GetFiles, File.ReadAllLines)
If you would like to edit the files in parallel. With threads you can parallelize work.
for (int i = 0; i < fileArray.Length; i++)
new Thread(UpdateFileThread).Start(fileArray[i]);
private void UpdateFileThread(object path)
{
string filePath = (string)path;
//ToDo: Edit file
}
In your case you would create 10 Threads. That solution works, but is a bad pattern if you have to deal with more than 10 files.
Below i have posted the real time code ,which i have used project
protected void btnSqlfinder_Click(object sender, EventArgs e)
{
//Defining the path of directory where all files saved
string filepath = # "D:\TPMS\App_Code\";
//get the all file names inside the directory
string[] files = Directory.GetFiles(filepath);
//loop through the files to search file one by one
for (int i = 0; i < files.Length; i++)
{
string sourcefilename = files[i];
StreamReader sr = File.OpenText(sourcefilename);
string sourceline = "";
int lineno = 0;
while ((sourceline = sr.ReadLine()) != null)
{
lineno++;
//defining the Keyword for search
if (sourceline.Contains("from"))
{
//append the result to multiline text box
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
if (sourceline.Contains("into"))
{
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
if (sourceline.Contains("set"))
{
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
if (sourceline.Contains("delete"))
{
TxtResult.Text += sourcefilename + lineno.ToString() + sourceline + System.Environment.NewLine;
}
}
}
}
This code will fetch the multiple files in the given directory,and show the lines as per the keyword in a separate text.
But you can easily change as per your requirement,Kindly let me know your thoughts.
Thanks

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

The full error I am receiving is:
"The process cannot access the file 'e:\Batch\NW\data_Test\IM_0232\input\RN318301.WM' because it is being used by another process.>>> at IM_0232.BatchModules.BundleSort(String bundleFileName)
at IM_0232.BatchModules.ExecuteBatchProcess()"
The involved code can be seen below. The RN318301.WM file being processed is a text file that contains information which will eventually be placed in PDF documents. There are many documents referenced in the RN318301.WM text file with each one being represented by a collection of rows. As can be seen in the code, the RN318301.WM text file is first parsed to determine the number of documents represented in it as well as the maximum number of lines in a documents. This information is then used to create two-dimensional array that will contain all of the document information. The RN318301.WM text file is parsed again to populate the two-dimensional array and at the same time information is collected into a dictionary that will be sorted later in the routine.
The failure occurs at the last line below:
File.Delete(_bundlePath + Path.GetFileName(bundleFileName));
This is a sporadic problem that occurs only rarely. It has even been seen to occur with a particular text file with which it had not previously occurred. That is, a particular text file will process fine but then on reprocessing the error will be triggered.
Can anyone help us to diagnose the cause of this error? Thank you very much...
public void BundleSort(string bundleFileName)
{
Dictionary<int, string> memberDict = new Dictionary<int, string>();
Dictionary<int, string> sortedMemberDict = new Dictionary<int, string>();
//int EOBPosition = 0;
int EOBPosition = -1;
int lineInEOB = 0;
int eobCount = 0;
int lineCount = 0;
int maxLineCount = 0;
string compareString;
string EOBLine;
//#string[][] EOBLineArray;
string[,] EOBLineArray;
try
{
_batch.TranLog_Write("\tBeginning sort of bundle " + _bundleInfo.BundleName + " to facilitate householding");
//Read the bundle and create a dictionary of comparison strings with EOB position in the bundle being the key
StreamReader file = new StreamReader(#_bundlePath + _bundleInfo.BundleName);
//The next section of code counts CH records as well as the maximum number of CD records in an EOB. This information is needed for initialization of the 2-dimensional EOBLineArray array.
while ((EOBLine = file.ReadLine()) != null)
{
if (EOBLine.Substring(0, 2) == "CH" || EOBLine.Substring(0, 2) == "CT")
{
if (lineCount == 0)
lineCount++;
if (lineCount > maxLineCount)
{
maxLineCount = lineCount;
}
eobCount++;
if (lineCount != 1)
lineCount = 0;
}
if (EOBLine.Substring(0, 2) == "CD")
{
lineCount++;
}
}
EOBLineArray = new string[eobCount, maxLineCount + 2];
file = new StreamReader(#_bundlePath + _bundleInfo.BundleName);
try
{
while ((EOBLine = file.ReadLine()) != null)
{
if (EOBLine.Substring(0, 2) == "CH")
{
EOBPosition++;
lineInEOB = 0;
compareString = EOBLine.Substring(8, 40).Trim() + EOBLine.Substring(49, 49).TrimEnd().TrimStart() + EOBLine.Substring(120, 5).TrimEnd().TrimStart();
memberDict.Add(EOBPosition, compareString);
EOBLineArray[EOBPosition, lineInEOB] = EOBLine;
}
else
{
if (EOBLine.Substring(0, 2) == "CT")
{
EOBPosition++;
EOBLineArray[EOBPosition, lineInEOB] = EOBLine;
}
else
{
lineInEOB++;
EOBLineArray[EOBPosition, lineInEOB] = EOBLine;
}
}
}
}
catch (Exception ex)
{
throw ex;
}
_batch.TranLog_Write("\tSending original unsorted bundle to archive");
if(!(File.Exists(_archiveDir + "\\" +DateTime.Now.ToString("yyyyMMdd")+ Path.GetFileName(bundleFileName) + "_original")))
{
File.Copy(_bundlePath + Path.GetFileName(bundleFileName), _archiveDir + "\\" +DateTime.Now.ToString("yyyyMMdd")+ Path.GetFileName(bundleFileName) + "_original");
}
file.Close();
file.Dispose();
GC.Collect();
File.Delete(_bundlePath + Path.GetFileName(bundleFileName));
You didn't close/dispose your StreamReader first time round so the file handle is still open
Consider using the using construct - this will automatically dispose of the object when it goes out of scope:
using(var file = new StreamReader(args))
{
// Do stuff
}
// file has now been disposed/closed etc
You need to close your StreamReaders for one thing.
StreamReader file = new StreamReader(#_bundlePath + _bundleInfo.BundleName);
You need to close the StreamReader object, and you could do this in a finally block:
finally {
file.Close();
}
A better way is to use a using block:
using (StreamReader file = new StreamReader(#_bundlePath + _bundleInfo.BundleName)) {
...
}
It looks to me like you are calling GC.Collect to try to force the closing of these StreamReaders, but that doesn't guarantee that they will be closed immediately as per the MSDN doc:
http://msdn.microsoft.com/en-us/library/xe0c2357.aspx
From that doc:
"All objects, regardless of how long they have been in memory, are considered for collection;"

Categories

Resources