I am currently working on a school project involving a large number of students where I have to insert a new student alphabetically and do a few other calculations. I am having trouble getting it so that it only adds the new student once. I have an if statement but it doesn't appear to be working properly.
`//this adds the new student
StreamWriter changeFile = new StreamWriter("Students.txt", true);
string newStudent = "(LIST (LIST 'Malachi 'Constant 'A ) '8128675309 'iwishihadjessesgirl#mail.usi.edu 4.0 )";
// this is where I am getting stumped
if (File.Exists(newStudent))
{
changeFile.Close();
}
else
{
changeFile.WriteLine(newStudent);
changeFile.Close();
}`
Whenever I run the code like this it will just add the new student every time I debug the program. How can I make it only add him one time?
File.Exists determines if the file at the given path exists (which, for the record, you should still be doing before trying to read/write to the file). You're trying to find out if the given line of text exists within a given file. That's a very different task.
You'll need to read through the lines in the file and compare them to your given text.
if(!File.ReadLines(filepath).Contains(newStudent))
{
//TODO: Append student to the file
}
File.Exists(string path) returns a bool that determines if a file exists at the specified path.
http://msdn.microsoft.com/en-us/library/system.io.file.exists(v=vs.110).aspx
string newStudent is not a file path, so it will always return false.
I think what you want is something like this: (this is by memory so it likely won't compile as is)
var file = File.Open("students.txt");
var fileContents = file.ReadToEnd();
if (!fileContents.Contains(newStudent))
{
file.WriteLine(newStudent);
}
file.Close();
First read the Existing file data into String variable and then check the given student data is available or not in the received file.if the given student data is not found then write the new student data into file otherwise,if already present then close the opened steream.
String StudentInfo = System.IO.File.ReadAllText("Students.txt");
StreamWriter changeFile = new StreamWriter("Students.txt", true);
string newStudent = "(LIST (LIST 'Malachi 'Constant 'A ) '8128675309 'iwishihadjessesgirl#mail.usi.edu 4.0 )";
// this is where I am getting stumped
if (StudentInfo.Contains(newStudent))
{
changeFile.Close();
}
else
{
changeFile.WriteLine(newStudent);
changeFile.Close();
}
Related
Ok, to cut a long story short I am doing load testing so I need to add 1000+ user credentials (email, password) to the DB. I have been using automated scripts using selenium and c# and would like to write a script to write this data into a csv file. I have random generators where I can make every email unique. I guess I would need a for loop for this? Anyone got the code for this? Btw once I have the csv file I already have a query to import the csv file into the DB.
So I found a script to add 2 columns but I am a total beginner so I haven't got a clue what to try, all google searches doesn't quite do what I am after even though the job should be quite simple.
public static void WriteToExcelMethod(string email, string passwd)
{
string path = #"c:\temp\MyTest.csv";
string line = String.Format(#"""{0}"",""{1}"", email, passwd);
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(line);
}
}
Is this a better script to write 2 columns and 1000 rows:
//before your loop
var csv = new StringBuilder();
//in your loop
var first = reader[0].ToString();
var second = image.ToString();
//Suggestion made by KyleMit
var newLine = string.Format("{0},{1}", first, second);
csv.AppendLine(newLine);
//after your loop
I saved my file in the database, I want to get that file for sending mail If I wrote where the condition
public EMS_PROFILE_UPLOAD_MASTER GetHrUploadeProfile(string EnqId)
{
var x = from n in db.EMS_PROFILE_UPLOAD_MASTER
where n.ENQUIRY_CODE== EnqId
select n;
foreach(var fileData in x)
{
var _FilData = fileData.FILEDATA;
}
return x.FirstOrDefault();
}
I'm getting data but here I have multiple files in my database, how can I differentiate that file?
The fact that you have multiple files with the same ID - means you cannot use the ID as the selector. Inside your code example, it seems that there may be other meta-data from that fileData object - what is inside that to further filter or control your selection for the correct file?
I am currently working on a code where I add a student to a text file of students and make other calculations. The problem I'm having is I have to sort the new student into the text file so he is in the correct place.
StreamWriter changeFile = new StreamWriter("Students.txt", true);
if (pos > 0)
{
changeFile.Close();
}
else
{
changeFile.WriteLine(newStudent);
changeFile.Close();
}
using (StreamReader streamReader = new StreamReader("Students.txt"))
{
string text = streamReader.ReadToEnd();
}
So far I have managed to change the text file into a string to compare the 2, but it is in the wrong place. What code would I use to make the StreamWriter compare the newStudent string to the text file so it can put it in the correct order?
P.S. The text file has over 10,000 students in it.
These are the first 5 lines of the text file:
students (LIST
(LIST (LIST 'Abbott 'A_____ 'J ) 'NONE 'xxxxx#mail.usi.edu 2.3073320999676614 )
(LIST (LIST 'Abbott 'B_____ 'Y ) 'NONE 'xxxxx#mail.usi.edu 3.1915725161177115 )
(LIST (LIST 'Abbott 'R_____ 'Y ) 'NONE 'xxxxx#mail.usi.edu 3.448215586562192 )
(LIST (LIST 'Abel 'H_____ 'Y ) 'NONE 'xxxxx#mail.usi.edu 3.2517764202656974 )
) ) <- this is at the end
Simple method is:
Split the string at the line breaks
Create a List containing the source lines
Add the new student to the list
Sort the list
Write the list to the file
Alternately:
Split the string at the line breaks
Create a List containing the source lines
Write lines back to the file util you find the position for the new record
Write the new record
Write the rest of the records.
Or, even better for large files:
Read the source file line-by-line
Write lines to a temporary destination file
When you find the correct place to insert the new record, write it to the dest file.
Continue copying lines from source to destination
Delete the source file and rename the destination file to take its place.
something like
var Students = File.ReadAllText("Students.txt").Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList().Union(new string[] { newStudent }).ToList().Sort();
File.WriteAllLines("Students.txt", Students);
might work for you
Assuming the text file contains one student per line, you could read the text file into a list of strings, then add the new student then sort it and write it back to the file.
var allStudents = new List<string>(File.ReadAllLines("Students.txt"));
allStudents.Add(newStudent);
allStudents.Sort(allStudents);
File.WriteLines("Students.txt", allStudents);
This is inefficient because every time it reads and writes the whole file. If you have a choice, consider using a database like others have suggested.
EDIT:
Since the first line of your file is not a student, you should remove it before sorting and re-add it later.
You can remove that line like this:
var line = allStudents[0];
allStudents.RemoveAt(0);
And re-add it like this:
allStudents.Insert(0, line);
I am facing some problem with deleting Names from NAmesManager in C# code.
As per my requirement, I need to delete all the Invalid names from the Names Manager. I am currently checking for the value of the Name and deleting it if the value is "#REF!". This is the code I am using
foreach (Name RangeName in namesManager2)
{
if(RangeName.Value.Contains("#REF!"))
{
RangeName.Delete();
}
}
The code works fine, However There are some strange situations where there exists 2 names with same Name but the scope is different.
Consider cell 1 is named "TESTNAME" with scope of "Workbook" and cell 2 is also named "TESTNAME" with scope "Sheet1". The name referring to Cell2 has a valid value.
So when I am looping if the name with "#REF!" value is encountered the above code is removing both the names. I want to retain the name with valid value but delete only the invalid Name.
Can someone suggest how to achieve this ?
There are bugs with duplicated Local/global names.
Accessing a global name whilst the active sheet has an identically named name local to that sheet, will change the properties of the local name and NOT the global name, even if the name is fully qualified with the workbook name.
So to bypass this you have to:
- detect if the Name is a duplicate
- if so switch to a worksheet that is not the parent of the local name (of course there may be multiple local names, one on each sheet so the only really safe way is to add another temporary worksheet and switch to that)
- then access whichever name you want either in the Workbook Name collection or the worksheet name collection.
This is the technique used by the freebie Name Manager Addin developed by JK Pieterse and myself:Name manager Download which has a lot more function than the built-in Name Manager
I recommend you use unique names for Name Ranges to avoid this sort of problem.
var activeBook = (Workbook)currentInstance.ActiveWorkbook;
Range rnArea = activeSheet.Range["A1:A1"];
activeBook.Names.Add("TESTNAME", rnArea);
rnArea = activeSheet.Range["B1:B1"];
activeSheet.Names.Add("TESTNAME", rnArea);
List<Name> existingNamedRangeList1 = XlHelper.GetNamedRanges(currentInstance.ActiveWorkbook);
foreach (Name RangeName in existingNamedRangeList1)
{
if (RangeName.Value.Contains("#REF!"))
{
RangeName.Delete();
}
}
Unfortunately, it looks like it assumes the Name will be unique, and as such any Deletes done will not have expected behaviour. One way to get around this is to generate a unique name when going through all the RangeNames, then after you are done deleting, reset them back to their original names.
var rangeNameHolder = new Dictionary<string, string>();
var rangeNames = activeBook.Names;
int counter = 0;
foreach (Name rangeName in rangeNames)
{
var oldName = rangeName.Name;
/*
* This hack here is done because when you grab the name, it includes the prepended scope.
* However, when you set the name, it prepends the scope yet again!
* So when you grab it the first time you need to remove the scope so that it doesnt get
* prepended twice
*/
oldName =oldName.Substring(oldName.LastIndexOf('!')+1);
var newName = string.Format("{0}{1}", oldName, counter++);
rangeName.Name = newName;
if (rangeName.Value.Contains("#REF!"))
{
rangeName.Delete();
continue;
}
rangeNameHolder.Add(rangeName.Name,oldName);
}
//Reset names back to original
foreach (Name rangeName in rangeNames)
{
if (rangeNameHolder.ContainsKey(rangeName.Name))
rangeName.Name = rangeNameHolder[rangeName.Name];
}
I am trying to write a program to scan a directory containing tv show folders, look up some details about the shows using tvrage API and then save the details to a database using entity framework.
My TVShow table pkey is the same value as taken from the tvrage database show id, and I am having issues when duplicate or similar folder names are returning the same Show info. In a situation where I have a directory containing three folders, "Alias", "Alias 1" , "Band of Brothers" I get the following output from my code
* TV SHOWS *
Alias....... NO MATCH......ADDING........DONE
Alias 1 ...... NO MATCH.....ADDING....CANT ADD, ID ALREADY EXISTS IN DB
Band of Brothers ...... NO MATCH..ADDING....
Before getting an UpdateException on the context.SaveChanges(); line
Violation of PRIMARY KEY constraint 'PK_TVShows'.
I can see using SQL profiler that the problem is that my app is trying to perform an insert on the alias show for a second time with duplicate key, but I can't see why. When I step through the code on the second interaction of the foreach loop (second "alias" folder), the code to save the show entity to the database is bypassed.
It is only on the next iteration of the foreach loop when I have created a new TVShow entity for "Band of Brothers" do I
actually reach the code which adds a Tvshow to context and saves, at which point the app crashes. In visual studio I can see
at the point of the crash that;
"show" entity in context.TVShows.AddObject(show) is "Band of Brothers" w/ a unique ID
context.TVShows only contains one record, the first Alias Entity
But SQL profiler shows that EntityFramework is instead inserting Alias for a second time, and I am stumped by why this is
private void ScanForTVShowFolders( GenreDirectoryInfo drive ) {
IEnumerable<DirectoryInfo> shows = drive.DirInfo.EnumerateDirectories();
foreach (DirectoryInfo d in shows) {
//showList contains a list of existing TV show names previously queried out of DB
if (showList.Contains(d.Name)) {
System.Console.WriteLine(d.Name + ".....MATCH");
} else {
System.Console.Write(d.Name + "......NO MATCH..ADDING....");
TVShow show = LookUpShowOnline(d.Name, drive.GenreName);
if (show.Id == -1) { // id of -1 means online search failed
System.Console.Write("..........CANT FIND SHOW" + Environment.NewLine);
} else if (context.TVShows.Any(a => a.Id == show.Id)) { //catch duplicate primary key insert
System.Console.Write(".......CANT ADD, ID ALREADY EXISTS IN DB" + Environment.NewLine);
} else {
context.TVShows.AddObject(show);
context.SaveChanges();
System.Console.Write("....DONE" + Environment.NewLine);
}
}
}
private TVShow LookUpShowOnline( string name, string genre ) {
string xmlPath = String.Format("http://services.tvrage.com/feeds/search.php?show='{0}'", name);
TVShow aShow = new TVShow();
aShow.Id = -1; // -1 = Can't find
XmlDocument xmlResp = new XmlDocument();
try { xmlResp.Load(xmlPath); } catch (WebException e) { System.Console.WriteLine(e); }
XmlNode root = xmlResp.FirstChild;
if (root.NodeType == XmlNodeType.XmlDeclaration) { root = root.NextSibling; }
XmlNode tvShowXML;
//if (showXML["episode"] == null)
// return false;
tvShowXML = root["show"];
if (tvShowXML != null) {
aShow.Id = System.Convert.ToInt16(tvShowXML["showid"].InnerText);
aShow.Name = tvShowXML["name"].InnerText.Trim();
aShow.StartYear = tvShowXML["started"].InnerText.Trim();
aShow.Status = tvShowXML["status"].InnerText.Trim();
aShow.TVGenre = context.TVGenres.Where(b => b.Name.Trim() == genre).Single();
}
return aShow;
}
}
Edit
Doing some more reading I added context.ObjectStateManager to my debug watchlist and I can see everytime I create a new TVShow entity a new record is added to _addedEntityStore. Actually if I remove context.TVShows.AddObject(show) the code still updates the database so manually adding to the context seems redundant.
If your are inserting object by foreach loop > better to keep the Primary Key outside and make it increment!
eg: int newID= Shows.Select(d=>d.Id).Max();
foreach(............)
{
show.Id = newID++;
.
.
. //remaining fields
.
context.TVShows.AddObject(show);
}
context.SaveChanges();
it works for me...!!
Turns out context.TVShows.AddObject(show) is unnecessary in my case, I was inadvertently adding all created show entities to the context when this query runs
aShow.TVGenre = context.TVGenres.Where(b => b.Name.Trim() == genre).Single();
This is not what I wanted, I just wanted to create the object, then decide whether to add it. Will be pretty easy to fix now I know why it's happening.