Save and load array in and from a file - c#

I need to save multidimensional array into file. Then be able to change things in that so it will also appear in that file and load from said file into array.
Let's say I have some array:
private string[,] array = new string[5, 5];
Then I need to do a function, that will fill the array with space if file does not exist and if it does, load it. Something like this:
private void Load()
{
if (File.Exists("save.txt"))
{
}
else
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
array[i,j] = " ";
}
}
}
}
I checked if the file exists, if not I will fill the array with spaces but then I need in some way write the array in the file in this format:
" ", " ", " "," ", " ",
" ", " ", " "," ", " ",
" ", " ", " "," ", " ",
" ", " ", " "," ", " ",
" ", " ", " "," ", " ",
or in some format, that will work.
Then I basically planned to split the string with ',' and save it to that array. And if file exists, read it and save the values to said array.
So basically I need to check if the file exist, if the answer is yes, load it to the multidimensional array, If the answer is no, fill the array with empty strings and load that in the file.
If somebody is willing to help me, I will be very grateful.

Related

ArgumentOutOfRangeException when I think my code should work

I'm working on a bit of code for school but I keep getting an ArgumentOutOfRangeException
With this code I'm trying to read some data from a .csv file and if it equals the name of the image I want it to remove it from the .csv file whilst keeping the structure intact.
public void checkPair(Image card1, Image card2)
{
this.Image1 = card1;
this.Image2 = card2;
if (Convert.ToString(card1.Source) == Convert.ToString(card2.Source) && (card1 != card2))
{
getPoint(card1, card2);
string path = #"Save1.csv";
var reader = new StreamReader(File.OpenRead(path));
var data = new List<List<string>>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
data.Add(new List<String> { values[0], values[1]
});
}
reader.Close();
string delimiter = ";";
for (int i = 1; i < 5; i++)
{
for (int x = 0; x < 4; x++)
{
if (data[i][x] == Convert.ToString(card1.Source))
{
data[i][x] = null;
}
}
}
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] + Environment.NewLine + data[1][0] + delimiter + data[1][1] + delimiter + data[1][2] + delimiter + data[1][3] + Environment.NewLine + data[2][0] + delimiter + data[2][1] + delimiter + data[2][2] + delimiter + data[2][3] + Environment.NewLine + data[3][0] + delimiter + data[3][1] + delimiter + data[3][2] + delimiter + data[3][3] + Environment.NewLine + data[4][0] + delimiter + data[4][1] + delimiter + data[4][2] + delimiter + data[4][3] + Environment.NewLine + "ready");
I have no idea why I get this error and how to fix it
Initially, I'd change your last line from
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] ....
to something like
var obj1 = data[0][0];
var obj2 = data[0][1];
File.WriteAllText(path, obj1 + delimiter + obj2 .... etc)
If you over inline functions or array accessing, when you get an exception the stack trace won't be that helpful. At least you'll have an idea of the statement that caused the issue.
This technique can prove to be very helpful, if you are looking at an in exception in the logs, after the fact.

Prevent last key in string to have a comma

Having trouble figuring out how to prevent the last key in my array to not have a comma. Since its being exported to a .Json file the last key shouldn't have a ",".
I know you can detect it by using .Last();, but I can't seem to make that work. Any recommendations?
//Data Path
string dataPath = #"..\..\FileIOExtraFiles\DataFieldsLayout.txt";
string[] dataList = File.ReadAllLines(dataPath);
//save Data data
using (StreamWriter outStream = new StreamWriter(outputFolder + #"\CharacterStringData3.json"))
{
outStream.WriteLine("{");
for (int i = 0; i < dataFile.Length; i++)
{
string s = dataFile[i];
char last = s.Last();
if (s == "")
{
outStream.WriteLine("\"" + dataList[i] + "\"" + " : " + "\" \",");
}
else
{
outStream.WriteLine("\"" + dataList[i] + "\"" + " : \"" + s + "\",");
}
}
outStream.WriteLine("}");
}
Output:
{
"data1":"item1",
"data2":item2",
"lastKey":item3",//trying to remove comma from last key in array.
}
As others have pointed out, it doesn't make sense that you are building json manually, but given that this is a question more about technique, here is one approach: you could change it to this:
var commaSuffix = (i == dataFile.Length - 1) ? "," : string.Empty;
outStream.WriteLine("\"" + dataList[i] + "\"" + " : \"" + s + "\"" + commaSuffix);
The suffix would be used on every iteration except the last.
Change this
outStream.WriteLine("\"" + dataList[i] + "\"" + " : " + "\" \",");
To this
outStream.WriteLine("\"" + dataList[i] + "\"" + " : " + "\" \""+(i==dataFile.Length?",":""));
Instead of using outStream.WriteLine() at every step, store it in a string. Then you can remove the last comma from that string and write the whole string at once:
//Get last index of comma
int lastCommaIndex = outputString.LastIndexOf(',');
//Create new StringBuilder with everything before the last comma
StringBuilder sb = new StringBuilder(outputString.Substring(0,lastCommaIndex));
//Add everything after the last comma, or just add a closing brace
//sb.Append("}"); //This instead of next line
sb.Append(outputString.Substring(lastCommaIndex+1));
//Add contents of StringBuilder to the Stream
outSteam.WriteLine(sb);

Display Output in a text file

I have taken the input code through file and i have to generate data according to it and output it's result in a text file as well..
My Output Code is below..
public void Generator()
{
/// ....... Code
public void DisplayTOKENS()
{
using (StreamWriter writer =
new StreamWriter("C:\\Users\\saeed\\Documents\\Outputt.txt"))
{
for (int i = 0; i < j;i++ )
{
tok[i].Display_Token();
} }
}
// and in other structur named TOKEN
public void Display_Token()
{ /*
using (StreamWriter writer =
new StreamWriter("C:\\Users\\saeed\\Documents\\Outputt.txt"))
{
writer.Write("( " + this.Class_Part + " , ");
writer.Write(this.Value_Part + " , ");
writer.Write(this.Line_no + " )");
writer.WriteLine();
}*/
Console.Write("( " + this.Class_Part + " , ");
Console.Write(this.Value_Part + " , ");
Console.Write(this.Line_no + " )");
Console.WriteLine();
}
When i try to directly work in Display_Token then it just simply show the last line in file.. i want to display the complete array in the file. waiting for some positive response !!
That StreamWriter constructor overwrites the existing file. So, each token effectively deletes whatever was written earlier then writes its content. That is why you only see the last token's content in the file.
Use the overload with the "append" argument and pass true so that the existing file is not deleted.
You have to check if file exists and than do "append" operation instead of "overwrite".
// in DisplayTOKENS()
string fileName = "C:\\Users\\saeed\\Documents\\Outputt.txt";
if (System.IO.File.Exists(fileName))
System.IO.File.Delete(fileName);
for (int i = 0; i < j; i++)
{
tok[i].Display_Token(fileName);
}
// in Display_Token(string fileName)
System.IO.File.AppendAllText(fileName, "( " + this.Class_Part + " , " + this.Value_Part + " , " + this.Line_no + " )");

Write to CSV and correct displaying in Excel 2010-2012

Help me please write every value to different cell, I try to write data in the CSV file but when I open this file in Excel the value showing in one line (cell). Did different various separators between the values "." and ",". But the results in Office 2010 and 2012 the same... And one more interesting think, in Office 2007 that work's with (*.xls)...
string s = "";
s += "Nick-Name, Category, Web-Pages, ICQ, Skype, Mail, Phone\r";
for (int i = 0; i < listOfUsers.Count; i+=3)
{
s += nickName[i] + "," + category[i] + "," + webList[i] + "," + ICQList[i] + "," + skypeList[i] + "," + mailList[i] + "," + phoneList[i] + ";\r";
}
System.IO.File.WriteAllText(#"" + folder + "Parse_people_list.csv", s, System.Text.Encoding.UTF8);
(source: pixs.ru)
(source: pixs.ru)
Try delimiting with tabs instead - Excel handles tab-delimited data better than comma-delimited since commas within the data may cause issues.
You can also use StringBuilder.AppendLine to improve performance and avoid adding line breaks manually:
StringBuilder s = new StringBuilder();
s.AppendLine("Nick-Name\tCategory\tWeb-Pages\tICQ\tSkype\tMail\tPhone");
for (int i = 0; i < listOfUsers.Count; i+=3)
{
s.AppendLine(
nickName[i] + "\t"
+ category[i] + "\t"
+ webList[i] + "\t"
+ ICQList[i] + "\t"
+ skypeList[i] + "\t"
+ mailList[i] + "\t"
+ phoneList[i]);;
}

better performance for algorithm

I have something like this:
using (SqlDataAdapter a = new SqlDataAdapter(query, c))
{
// 3
// Use DataAdapter to fill DataTable
DataTable t = new DataTable();
a.Fill(t);
string txt = "";
for (int i = 0; i < t.Rows.Count; i++)
{
txt += "\n" + t.Rows[i][0] + "\t" + t.Rows[i][1] + "\t" + t.Rows[i][2] + "\t" + t.Rows[i][3] + "\t" + t.Rows[i][4] + "\t" + t.Rows[i][5] + "\t" + t.Rows[i][6] + "\t" + t.Rows[i][7] + "\t" + t.Rows[i][8] + "\t" + t.Rows[i][9] + "\t" + t.Rows[i][10] + "\t" + t.Rows[i][11] + "\t" + t.Rows[i][12] + "\t" + t.Rows[i][13] + "\t" + t.Rows[i][14] + "\t" + t.Rows[i][15] + "\t" + t.Rows[i][16] + "\t" + t.Rows[i][17] + "\t" + t.Rows[i][18] + "\t" + t.Rows[i][19];
}
}
I need this tabs between columns to generate txt file later.
Problem is that t.Rows.Count = 600000 and this loop works 9 hours.
Any ideas how to make this faster?
Regards
kazik
Use a StringBuilder instead of concatenating your strings.
string txt = "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < t.Rows.Count; i++)
{
sb.Append(t.Rows[i][0]);
sb.Append("\t");
sb.Append(t.Rows[i][1]);
//and so on...
}
string txt = sb.ToString();
Adding a string to another string (by assigning it back again) takes effort relative to the length of the combined string - this gets very costly fast for large strings - it is a Schlemiel the Painter's algorithm. Using a StringBuilder avoids this since no new string have to be created every time you add a new string to its content.
I have to question though why you keep all of this data in memory just to write it out to a file - you should switch to a model that allows you to generate line by line of the text content, I would suggest using a data reader instead and method that yields text lines, e.g.:
public IEnumerable<string> GenerateTextOutput()
{
//...
//using SqlDataReader instead
while(reader.Read())
{
//assemble string for next row
string txt = "...";
yield return txt;
}
}
Then you can just write this output to disk:
File.WriteAllLines("foo.txt", GenerateTextOutput());
Use StringBuilder. You can find examples everywhere on the web.
Others mentioned StringBuilder, and they are correct. However, note that in .NET 4 StringBuilder became more efficient, avoiding reallocations and memory copying altogether. If you're using a previous version of .NET, you will get worse performance. It will still beat what you're doing.
I wonder what you're doing with txt after it's ready. You might want to avoid storing the string in memory altogether, and write it directly to a file (I don't believe you're showing your users 600,000 lines...)
StringBuilder has already been mentioned by others and should provide significant benefit.
Do you really need to keep the entire text in memory with 600K rows? You can speed this up a lot by directly writing to the file.
And for that many iterations, assigning Rows[i] to a variable might also provide some extra spped-up.

Categories

Resources