How I can close a text file after I edited? - c#

I have a text file installer_input.txt and a checkedListBox2 in a form application. I want to edit the text file if I have some changes in checkesListBox2. I have two parts of code, I know that are so long, but I need some help :
private void checkedListBox2_SelectedIndexChanged(object sender, EventArgs e)
{
string path = AppDomain.CurrentDomain.BaseDirectory.ToString();
var lin = (path + "config.ini").ToString();
var lines = File.ReadAllLines(lin);
string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile="))
.Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault();
string pathTemp = #"C:\temp\";
string[] pathArr = InstallerFile.Split('\\');
string[] fileArr = pathArr.Last().Split('\\');
string fileArr1 = String.Join(" ", fileArr);
string installerfilename = string.Format("{0}{1}", pathTemp, fileArr1);
IEnumerable<string> inilines = File.ReadAllLines(installerfilename).AsEnumerable();
bool IsChecked = checkedListBox2.CheckedItems.Contains(checkedListBox2.SelectedItem);
else if (fileArr1.Equals("installer_input.txt"))
{
if (IsChecked && checkedListBox2.CheckedItems.Count != checkedListBox2.Items.Count)
inilines = inilines.Select(line => line == string.Format("#product.{0}", checkedListBox2.SelectedItem)
? Regex.Replace(line, string.Format("#product.{0}", checkedListBox2.SelectedItem), string.Format(#"product.{0}", checkedListBox2.SelectedItem))
: line);
else if (!IsChecked || checkedListBox2.CheckedItems.Count == checkedListBox2.Items.Count)
inilines = inilines.Select(line => (line == string.Format("product.{0}", checkedListBox2.SelectedItem))
? Regex.Replace(line, string.Format(#".*product.{0}", checkedListBox2.SelectedItem), string.Format(#"#product.{0}", checkedListBox2.SelectedItem))
: line);
if (checkedListBox2.CheckedItems.Count == checkedListBox2.Items.Count)
checkBox1.Checked = true;
else
checkBox1.Checked = false;
string strWrite = string.Join(Environment.NewLine, inilines.ToArray());
File.WriteAllText(installerfilename, strWrite);
}
}
And the second code is :
private void checkBox1_CheckedChanged_1(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
SetAllItemsChecked(cb.Checked);
var installerLines = ReadInstallerLines();
SetAllProductsChecked(installerLines.ToList(), cb.Checked);
SaveInstaller(installerLines);
}
private void SetAllItemsChecked(bool check)
{
for (int i = 0; i < this.checkedListBox2.Items.Count; i++)
{
this.checkedListBox2.SetItemChecked(i, check);
}
}
private IEnumerable<string> ReadInstallerLines()
{
var lin = (path + "config.ini").ToString();
var lines = File.ReadAllLines(lin);
string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile="))
.Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault();
string pathTemp = #"C:\temp\";
string[] pathArr = InstallerFile.Split('\\');
string[] fileArr = pathArr.Last().Split('\\');
string fileArr1 = String.Join(" ", fileArr);
string installerfilename = pathTemp + fileArr1;
string installertext = File.ReadAllText(installerfilename);
return File.ReadLines(pathTemp + fileArr1);
}
private void SetAllProductsChecked(IList<string> installerLines, bool check)
{
for (var i = 0; i < installerLines.Count; i++)
{
if (installerLines[i].Contains("product="))
{
installerLines[i] = check
? installerLines[i].Replace("#product", "product")
: installerLines[i].Replace("product", "#product");
}
if (installerLines[i].Contains("product."))
{
installerLines[i] = check
?installerLines[i].Replace("#product.", "product.")
: installerLines[i].Replace("product.", "#product.");
}
}
}
private void SaveInstaller(IEnumerable<string> installerLines)
{
var lin = (path + "config.ini").ToString();
var lines = File.ReadAllLines(lin);
string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile="))
.Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault();
string pathTemp = #"C:\temp\";
string[] pathArr = InstallerFile.Split('\\');
string[] fileArr = pathArr.Last().Split('\\');
string fileArr1 = String.Join(" ", fileArr);
string installerfilename = pathTemp + fileArr1;
File.WriteAllLines(installerfilename, installerLines);
}
}
First works, I can check the boxes from the list, but when I try to make click on checkBox1 I have the next error: The process cannot access the file 'C:\temp\installer_input.txt' because it is used by another process.
How I can make program to works? And how I can optimize my code ?

Basically a single thread/process can access a resource which is the file in this case at one instance what you can do is use EventWaitHandle to wait untill some other process or thread has occupied the file like this:
EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES");
waitHandle.WaitOne();
/* process file*/
waitHandle.Set();

Related

unable to read PDF controls in c#

Am tryinng to read PDf and inside PDF controls. my pdf is generated by adobe pdf library. getting null acro fields.but my form have 4 check boxes. 4 check boxed i can use to check or uncheck . i want checkbox is checked or not.
i used itextsharp to read pdf but, it is not finding controls.
private static string GetFormFieldNamesWithValues(PdfReader pdfReader)
{
return string.Join("\r\n", pdfReader.AcroFields.Fields
.Select(x => x.Key + "=" +
pdfReader.AcroFields.GetField(x.Key) + "=" + pdfReader.AcroFields.GetFieldType(x.Key)).ToArray());
}
static void Main(string[] args)
{
DataTable filedDetails;
DataRow dr;
string cName="";
string cType = "";
string cValue = "";
int txtCount = 0;
int btnCount = 0;
int chkBoxCount = 0;
int rdButtonCount = 0;
int dropDownCount = 0;
var fileName = "C:\\PreScreenings\\ViewPDF Cien.pdf";// PDFFileName.Get(context);
//var fileName = #"C:\Users\465sanv\Downloads\Read-PDF-Controls-master\ReadPDFControl\Input\David1990.pdf";
var fields = GetFormFieldNamesWithValues(new PdfReader(fileName));
string[] splitRows = fields.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
filedDetails = new DataTable("PDF Table");
filedDetails.Columns.AddRange(new[] { new DataColumn("Control Name"), new DataColumn("Control Type"), new DataColumn("Control Value") });
foreach (string row in splitRows)
{
dr = filedDetails.NewRow();
string[] str = row.Split("=".ToCharArray(), StringSplitOptions.None);
cName = str[0].ToString();
cValue = str[1].ToString();
if (str[2].ToString() == "1")
{
btnCount++;
cType = "Button" + btnCount.ToString();
}
else if (str[2].ToString() == "2")
{
chkBoxCount++;
cType = "Check Box" + chkBoxCount.ToString();
}
else if (str[2].ToString() == "3")
{
rdButtonCount++;
cType = "Radio Button" + rdButtonCount.ToString();
}
else if (str[2].ToString() == "4")
{
txtCount++;
cType = "Text Field" + txtCount.ToString();
}
else if (str[2].ToString() == "6")
{
dropDownCount++;
cType = "Drop Down" + dropDownCount.ToString();
}
dr[0] = cName;
dr[1] = cType;
dr[2] = cValue;
filedDetails.Rows.Add(dr);
}
}

How to do unit test on a method that has StreamReader and Database access

I have never done unit tests before. I'd like to learn how to do it. I'd like to use Visual Studio unit test and moq.
My project is transferring data from interbase to SQL Server. Firstly, I extract data from interbase into a plain text file. The layout is FieldName + some spaces up to 32 char length + field value. Then, I write a method that reads the text file line by line; once it reaches the next record, it inserts the current record into SQL Server.
So it involves in stream reader and SQL database insertion. For the stream reader, I read some post on the Internet and I pass the Stream reader as the method's parameter; but the SQL Server part, I have no idea how to simplify my method so that it can be tested.
I really need your help.
public partial class TableTransfer
{
#region declare vars
public string FirstFldName = "";
public string ErrorMsg = "";
public List<MemoBlobTrio> MemoBlobs = null;
public string SqlServerTableName = "";
#endregion
public bool DoTransfer(System.IO.StreamReader sr, Func<TransferShare, string, string, bool> TransferTable)
{
#region declare var
bool DoInsert = true;
TransferShare transferShare = null;
string line = string.Empty;
string blobLines = string.Empty;
string fldName = string.Empty;
string value = string.Empty;
bool Is1stLine = true;
bool isMemoFld = false;
MemoBlobTrio memoBlobTrio = null;
int idx = 0;
#endregion
try
{
using(sr)
{
transferShare = new TransferShare();
ConnectSQLServer(transferShare);
transferShare.StartInsert(SqlServerTableName);
bool readNext = true;
do
{
try
{
if (readNext)
line = sr.ReadLine();
if ((line != null) && (line.Trim() != ""))
{
fldName = line.Length > 30 ? line.Substring(0, 31).TrimEnd() : "";
Is1stLine = fldName == FirstFldName;
if (Is1stLine)
{
if (DoInsert)
EndInsert(transferShare, line);
else
transferShare.ClearSQL();
DoInsert = true;
}
idx = 0;
isMemoFld = false;
while (idx < MemoBlobs.Count)
{
if (fldName == (MemoBlobs[idx] as MemoBlobTrio).fbFldName)
{
memoBlobTrio = MemoBlobs[idx] as MemoBlobTrio;
line = InsertMemoBlob(transferShare, sr, memoBlobTrio.ssFldName, fldName, memoBlobTrio.fbNextFldName);
readNext = false;
isMemoFld = true;
}
idx++;
}
if (!isMemoFld)
{
if (line.Length > 31)
value = line.Remove(0, 31);
else
value = "";
if (!TransferTable(transferShare, fldName, value))
DoInsert = false;
readNext = true;
}
}
}
catch (Exception err)
{
HandleError(err, line);
}
} while (line != null);
if (DoInsert)
EndInsert(transferShare, line);
}
}
finally
{
transferShare.SQLConn.Dispose();
}
return true;
}
private static void ConnectSQLServer(TransferShare transferShare)
{
TransferShare.SQLServerConnStr = "Data Source=" + Environment.MachineName + "\\SQLEXPRESS;Initial Catalog=MyDB;Integrated Security=True";
transferShare.SQLConn.ConnectionString = TransferShare.SQLServerConnStr;
transferShare.SQLConn.Open();
}
}
public class TransferShare
{
public void StartInsert(string TableName)
{
tableName = TableName;
}
public void EndInsert(TransferShare transferShare, string line)
{
SqlCommand Cmd = null;
try
{
sqlInsFld = sqlInsFld.Remove(sqlInsFld.Length - 1);
sqlInsValue = sqlInsValue.Remove(sqlInsValue.Length - 1);
sqlInsFld = "Insert into " + tableName + " (" + sqlInsFld + ")";
sqlInsValue = " Values (" + sqlInsValue + ")";
Cmd = new SqlCommand(sqlInsFld + sqlInsValue, SQLConn);
Cmd.ExecuteNonQuery();
}
catch (Exception err)
{
throw (new Exception(err.Message));
}
finally
{
sqlInsFld = "";
sqlInsValue = "";
}
}
}

Google map locations sorted by nearest first on map

I'm using google map API. I have 4 destinations and I want to get their locations ordered by nearest location first followed by second nearest. I have to show on Google Map which location is 1st being the nearest and then the next nearest and so on. So far I have only successfully calculated the distance between 2 locations by using below code:
private void button1_Click(object sender, EventArgs e)
{
getDistance("DECATUR FARM ROAD CHICHESTER PO20 8JT", "UNIT 01 CLIFF REACH GREENHITHE DA9 9SW");
}
public int getDistance(string origin, string destination)
{
System.Threading.Thread.Sleep(1000);
int distance = 0;
//string from = origin.Text;
//string to = destination.Text;
string url = "http://maps.googleapis.com/maps/api/directions/json?origin=" + origin + "&destination=" + destination + "&sensor=false";
string requesturl = url;
//string requesturl = #"http://maps.googleapis.com/maps/api/directions/json?origin=" + from + "&alternatives=false&units=imperial&destination=" + to + "&sensor=false";
string content = fileGetContents(requesturl);
JObject o = JObject.Parse(content);
try
{
distance = (int)o.SelectToken("routes[0].legs[0].distance.value");
return distance;
}
catch
{
return distance;
}
return distance;
//ResultingDistance.Text = distance;
}
protected string fileGetContents(string fileName)
{
string sContents = string.Empty;
string me = string.Empty;
try
{
if (fileName.ToLower().IndexOf("http:") > -1)
{
System.Net.WebClient wc = new System.Net.WebClient();
byte[] response = wc.DownloadData(fileName);
sContents = System.Text.Encoding.ASCII.GetString(response);
}
else
{
System.IO.StreamReader sr = new System.IO.StreamReader(fileName);
sContents = sr.ReadToEnd();
sr.Close();
}
}
catch { sContents = "unable to connect to server "; }
return sContents;
}
How do I show the destinations according to their distance on google map. Any tip or pointers will be appreciated.
Please see the image, this is what I am trying to accomplish
Happy :) Enjoy Coding..
ArrayList arraylist;
List<string> adddistance = new List<string>();
List<string> getfinallist = new List<string>();
private void button1_Click(object sender, EventArgs e)
{
string s = "UNIT 01 CLIFF REACH GREENHITHE DA9 9SW,PINETOP BIRKLANDS LANE ST ALBANS AL1 1EE,HOLYWELL HILL ST ALBANS AL1 1BT,OLD RECTORY HOLYWELL HILL ST ALBANS AL1 1BY";
button("DECATUR FARM ROAD CHICHESTER PO20 8JT", s);
}
public void button(string orign , string destination)
{
string[] words = destination.Split(',');
foreach (string word in words)
{
getDistance(orign, word);
}
sorting();
}
public int getDistance(string origin, string destination)
{
System.Threading.Thread.Sleep(1000);
int distance = 0;
string url = "http://maps.googleapis.com/maps/api/directions/json?origin=" + origin + "&destination=" + destination + "&sensor=false";
string requesturl = url;
string content = fileGetContents(requesturl);
JObject o = JObject.Parse(content);
string strdistance = (string)o.SelectToken("routes[0].legs[0].distance.value") + " , " + destination + " , ";
adddistance.Add(strdistance);
return distance;
}
public void sorting()
{
adddistance.Sort();
string getfirststring = adddistance.FirstOrDefault().ToString() ;
var vals = getfirststring.Split(',')[1];
getfinallist.Add(getfirststring.Split(',')[1]);
StringBuilder builder = new StringBuilder();
adddistance.RemoveAt(0);
foreach (string cat in adddistance) // Loop through all strings
{
builder.Append(cat); // Append string to StringBuilder
}
adddistance.Where((wors, index) => index % 2 == 0);
string result = builder.ToString();
string[] words = result.Split(',');
string[] even = words.Where((str, ix) => ix % 2 == 1).ToArray();
adddistance.Clear();
foreach (string word in even)
{ //string get = Regex.Match(word, #"^[" + numSet + #"]+$").ToString();
if (word != " ")
{
getDistance(vals, word);
}
}
sorting();
}
protected string fileGetContents(string fileName)
{
string sContents = string.Empty;
string me = string.Empty;
try
{
if (fileName.ToLower().IndexOf("http:") > -1)
{
System.Net.WebClient wc = new System.Net.WebClient();
byte[] response = wc.DownloadData(fileName);
sContents = System.Text.Encoding.ASCII.GetString(response);
}
else
{
System.IO.StreamReader sr = new System.IO.StreamReader(fileName);
sContents = sr.ReadToEnd();
sr.Close();
}
}
catch { sContents = "unable to connect to server "; }
return sContents;
}

Reading large number of text files using task (TPL)

I am reading around 300 txt files using the task concept. My requirement is to read each file , pick the date from every line , check in which week it comes and then compare it with the folder name which are actually the week names (like 41 , 42) whether they both are same or not. if not then write that file name and the line number. As the number of files and the size of files is huge , I am trying to use task concept to that I can speed up the process. Below is my code.
Any help would be appreciated. Thanks in advance.
private void browse_Click(object sender, EventArgs e)
{
try
{
string newFileName = "";
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
DateTime starttime = DateTime.Now;
string folderPath = Path.GetDirectoryName(folderBrowserDialog1.SelectedPath);
DirectoryInfo dInfo = new DirectoryInfo(folderPath);
string[] Allfiles = Directory.EnumerateFiles(folderPath, "*.txt", SearchOption.AllDirectories).ToArray();
foreach (DirectoryInfo folder in dInfo.GetDirectories())
{
newFileName = "Files_with_duplicate_TGMKT_Names_in_child_Folder_" + folder.Name + ".txt";
if (File.Exists(folderPath + "/" + newFileName))
{
File.Delete(folderPath + "/" + newFileName);
}
FileInfo[] folderFiles = folder.GetFiles();
if (folderFiles.Length != 0)
{
List<Task> tasks = new List<Task>();
foreach (var file in folderFiles)
{
var task = Task.Factory.StartNew(() =>
{
bool taskResult = ReadFile(file.FullName,folderPath,newFileName);
return taskResult;
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
DateTime stoptime = DateTime.Now;
TimeSpan totaltime = stoptime.Subtract(starttime);
label6.Text = Convert.ToString(totaltime);
textBox1.Text = folderPath;
DialogResult result2 = MessageBox.Show("Read the files successfully.", "Important message", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
catch (Exception)
{
throw;
}
}
public bool ReadFile(string file , string folderPath , string newFileName)
{
int LineCount = 0;
string fileName = Path.GetFileNameWithoutExtension(file);
using (FileStream fs = File.Open(file, FileMode.Open))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
for (int i = 0; i < 2; i++)
{
sr.ReadLine();
}
string oline;
while ((oline = sr.ReadLine()) != null)
{
LineCount = ++LineCount;
string[] eachLine = oline.Split(';');
string date = eachLine[30].Substring(1).Substring(0, 10);
DateTime Date = DateTime.ParseExact(date, "d", CultureInfo.InvariantCulture);
int week = new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(Date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Saturday);
if (Convert.ToString(week) == folderName)
{
}
else
{
using (StreamWriter sw = new StreamWriter(folderPath + "/" + newFileName, true))
{
Filecount = ++Filecount;
sw.WriteLine(fileName + " " + "--" + " " + "Line number :" + " " + LineCount);
}
}
}
}
return true;
}
Your call MessageBox.Show inside ReadFile, which means every file has to write a message. This way you will get 300 messages.
Try to put your message after the WaitAll call outside the ReadFile method.
if (files.Length != 0)
{
List<Task> tasks = new List<Task>();
foreach (var file in files)
{
var task = Task.Factory.StartNew(() =>
{
bool taskResult = ReadFile(file);
return taskResult;
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
// Message here
DialogResult result2 = MessageBox.Show("Read the files successfully.", "Important message", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

No overload for 'button1_Click' matches delegate

I don't understand why I get this error... Can anyone help me?
private void button1_Click(object sender, EventArgs e, string filePath)
{
OpenFileDialog of = new OpenFileDialog();
of.ShowDialog();
Filenametext.Text = of.FileName;
//Create an instance for the openbox dialog
//And opens the explorer to select the wanted file.
{
DataRow row;
DataService m_WsData = new DataService();
string XMLFileName = ConfigurationSettings.AppSettings["XMLPath"].ToString() + DateTime.Now.Ticks.ToString() + ".xml";
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs, System.Text.Encoding.GetEncoding("ISO-8859-1"));
{
DataSet ds = m_WsData.GEDS();
string line = "";
int lineNo = 0;
string lineStart = "";
string lineEnd = "";
string[] fileRow;
{
line = sr.ReadLine();
if (line != null)
{
fileRow = line.Split(new Char[] { ';' });
if (lineNo == 0)
{
lineStart = fileRow[0];
}
if (fileRow[0] != "00" && fileRow[0] != "99")
{
row = ds.Tables["FuelFileData"].NewRow();
row["TransNo"] = fileRow[0];
row["CustomerNo"] = fileRow[1];
row["TruckNo"] = fileRow[2];
row["FuelDate"] = fileRow[3];
row["FuelTime"] = fileRow[4];
row["Place"] = fileRow[5];
row["FuelTypeNo"] = fileRow[6];
row["FuelDescription"] = fileRow[7];
row["DriverNo"] = fileRow[8];
row["Blank"] = fileRow[9];
row["TransType"] = fileRow[10];
row["Fuel"] = fileRow[11];
row["FuelCost"] = fileRow[12];
row["MileageFile"] = fileRow[13];
row["DrivenKm"] = fileRow[14];
row["AverageConsFile"] = fileRow[15];
//row["ImportedGuid"]=fileRow[16];
}
lineEnd = fileRow[0];
lineNo++;
}
} while (line != null);
lineStart = lineStart.Trim() + lineEnd.Trim();
fs.Close();
if (lineStart == "0099")
{
ds.WriteXml(XMLFileName);
System.IO.File.Delete(XMLFileName);
}
}
}
}
Cause
You cannot add parameters on event handler methods.
The Click event is defined as
public event RoutedEventHandler Click;
which means that the handler must match the delegate RoutedEventHandler which is
public delegate void RoutedEventHandler(Object sender, RoutedEventArgs e);
Solution
Remove the string filePath parameter and pass the path via a public property.

Categories