asp.net c# txt file to dropdownlist: - c#

I need to populate a drop down list with a txt file. I tried this but it isn't working.
protected void DropDownListCOUNTRY_SelectedIndexChanged(object sender, EventArgs e)
{
List<string> country = new List<string>();
country = File.ReadAllLines("../App_Data/txt/CountryList.txt").Select(x => x.Split('_')[0]).ToList();
foreach (string countrysingle in country)
{
DropDownListCOUNTRY.Items.Add(new ListItem(countrysingle, countrysingle));
}
}
This is the VB code that works in C#
if (this.IsPostBack == false)
{
string path = MapPath("~/App_Data/txt/CountryList.txt");
FileStream fp = new FileStream(path, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(fp);
string data;
while ((data = reader.ReadLine()) != null)
{
string[] v = data.Split(',');
foreach (string entry in v)
{
DropDownListCOUNTRY.Items.Add(entry);
}
}
reader.Close();
fp.Close();
}

The VB code in my initial question works.

I think you have to give variable declaration also in foreach loop like below
foreach (string countrysingle in country) {
DropDownListCOUNTRY.Items.Add(countrysingle);
}

Related

How can I reduce memory usage when parse json in c#

I'm trying to parse huge json file to 2d array.
I can parse. But required memory is almost 10times.
My sample.json file has 100,000 rows, each with a different item.
If sample.json is 500MB this code need 5GB.
How can i reduce memory usage?
I use Newtonsoft.Json, .Net6.0
Read from json
static void Read()
{
List<Dictionary<string, string>> rows = new List<Dictionary<string, string>>();
string path = #"D:\small.json";
using (FileStream fsRead = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bsRead = new BufferedStream(fsRead))
using (StreamReader srRead = new StreamReader(bsRead))
{
string? line;
while ((line = srRead.ReadLine()) != null)
{
JObject jsonObject = JObject.Parse(line);
MakeRowData(jsonObject, out var row);
rows.Add(row);
}
}
}
Make row
private static void MakeRowData(JObject jsonData, out Dictionary<string, string> row)
{
Dictionary<string, string> output = new Dictionary<string, string>();
foreach (var item in jsonData)
{
int childSize = 0;
if (item.Value != null)
{
childSize = item.Value.Children().Count();
///if Item has child, explore deep
if (childSize > 0)
{
ExploreChild(item.Value, ref output);
}
///or not just add new item
else
{
string str = item.Value.ToString();
output[item.Key] = str ?? "";
}
}
}
row = output;
}
private static void ExploreChild(JToken jToken, ref Dictionary<string, string> row)
{
foreach (var item in jToken)
{
int childSize = item.Children().Count();
///if Item has child, explore deep
if (childSize > 0)
{
ExploreChild(item, ref row);
}
///or not just add new item
else
{
string path = jToken.Path.Replace('[', '(').Replace(']', ')');
string str = jToken.First.ToString();
row[path] = str?? "";
}
}
}
EDIT
Add Sample.json
It is set of json strings.
And Fields are not fixed.
Sample.json
{Field1:0,Field2:1,Field2:3}
{Field1:0,Field5:1,Field6:3}
{Field1:0,Field7:1,Field9:3}
{Field1:0,Field13:1,Field50:3,Field57:3}
...
You can try replacing the recursive exploring children with the iterative one. Something like this:
private static void MakeRowData(JObject jsonData, out Dictionary<string, string> row)
{
Dictionary<string, string> output = new Dictionary<string, string>();
foreach (var item in jsonData)
{
if (item.Value != null)
{
///if Item has child, explore deep
if (item.Value.HasValues)
{
var queue = new Queue<JToken>();
queue.Enqueue(item.Value);
while (queue.Any())
{
var currItem = queue.Dequeue();
if (currItem.HasValues)
{
foreach(var child in item)
queue.Enqueue(child);
}
else
{
// add item without children to row here
}
}
}
///or not just add new item
else
{
string str = item.Value.ToString();
output[item.Key] = str ?? "";
}
}
}
row = output;
}
Recursive calls, unless it is a tail recursion, keep the stack of a method they were called from. This can lead to extensive memory usage.

How to delete selected Item from a listbox

I have created a DeleteSlectedItemListBox Method below which has a code that deleted a selected item in the list-box when delete button has been clicked. However it does not seem like its working.
The code has to delete whats on the list-box as well in the text-file.
How do I do that ?
private void DeleteSelectedItemListBox()
{
DataTable dt = new DataTable();
string FileName = (#"C: \Users\StanleyM\Desktop\PhoneBook\PhoneBook\bin\Debug\Personal.text");
StreamReader streamReader = new StreamReader(FileName);
string line = "";
int Counter = -1;
while ((line = streamReader.ReadLine()) != null)
{
foreach (var item in line)
{
if (item.ToString() == SelectedItem.ToString())
{
Counter--;
dt.Clear();
ListBox.Remove(line);
}
}
}
}
If you are using MVVM pattern you can bind in XAML selected item and your list like ObservableCollention. <ListBox ItemsSource="{Binding YourList}" SelectedItems="{Binding YourSelectedItem}"></ListBox>
Then in your deleting method you can try:
private void DeleteSelectedItemListBox()
{
var deletingNumber = YourList.IndexOf(YourSelectedItem);
var allLines = File.ReadAllLines(path).ToList();
allLines.RemoveAt(deletingNumber);
File.WriteAllLines(path,allLines.ToArray());
}
while (listBox1.SelectedItems.Count > 0)
{
var index = listBox1.Items.IndexOf(listBox1.SelectedItem);
listBox1.Items.RemoveAt(index);
RemoveTextLine(index);
}
private void RemoveTextLine(int index){
using(var sr = new StreamReader("C:\Users\StanleyM\Desktop\PhoneBook\PhoneBook\bin\Debug\Personal.text"))
using(var sw = new StreamWriter("C:\Users\StanleyM\Desktop\PhoneBook\PhoneBook\bin\Debug\temp.text"))
{
int line=0;
while((sr.ReadLine()) != null)
{
if(line != index)
sw.WriteLine(line);
line ++;
}
}
File.Delete("Personal.txt");
File.Move(tempFile, "Personal.txt");
}
Try This

Creating specific list of Items for each file in a Directory using C#

I am trying to create a List for every file available in a directory. Each file must have a separate list of items. I have created a list, but it shows all items available in all files. How to do it? Need help in this regard.
I am doing it like this, but it shows all Items "Product" in all files:
a piece of code is here:
List products = new List();
foreach (string file in fileList)
{
using (StreamReader sr = new StreamReader(file))
{
string line;
while ((line = sr.ReadLine()) != null)
{
rows++;
if (line.StartsWith("Product"))
{
var val = line.Split(',');
upc = val[1];
pName = val[3];
products.Add(upc);
products.Add(pName);
productList = string.Join(",", products.ToArray());
Add these clases
public class ProductFile
{
public string Name;
public List<Product> Products = new List<Product>();
}
public class Product
{
public string Upc;
public string PName;
}
And then, in your code:
var productFiles = new List<ProductFile>();
foreach (string file in fileList)
{
var productFile = new ProductFile(){ Name = Path.GetFileName(file) };
using (StreamReader sr = new StreamReader(file))
{
string line;
while ((line = sr.ReadLine()) != null)
{
rows++;
if (line.StartsWith("Product"))
{
var val = line.Split(',');
var product = new Product()
{
Upc = val[1],
PName = val[3]
};
productFile.Products.Add(product); //Adds a product
}
}
};
productFiles.Add(productFile); //Adds a file
}

How can i edit a cell from the datgridview?

I have asked this question yesterday and i didn't get good response. i am working on a resx file. I have read the file and load it on data-gridview. now i wanted to be able to edit from the file and save.I have tried many ways but i didn't come with the solution. yesterday i tried this code below. I don't know how i can edit. please help me.
private void btnSave_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow _row in Gridview_Output.Rows)
{
DataRow dt1 = oDataTable.NewRow();
for (int i = 0; i < Gridview_Output.ColumnCount; i++)
{
Gridview_Input.SelectedRows[0].Cells[1].Value = oDataSet.Tables["data"].Rows[0][1].ToString();
Gridview_Input.SelectedRows[0].Cells[2].Value = oDataSet.Tables["data"].Rows[0][2].ToString();
Gridview_Input.SelectedRows[0].Cells[3].Value = oDataSet.Tables["data"].Rows[0][3].ToString();
Gridview_Input.SelectedRows[0].Cells[4].Value = oDataSet.Tables["data"].Rows[0][4].ToString();
oDataTable.Rows.Add(dt1);
}
oDataSet.Tables.Add(oDataTable);
oDataSet.WriteXml(PathSelection);
}
This will help you almost the way you want it.
Code snippet from Modifying .resx file in c#
public static void UpdateResourceFile(Hashtable data, String path)
{
Hashtable resourceEntries = new Hashtable();
//Get existing resources
ResXResourceReader reader = new ResXResourceReader(path);
if (reader != null)
{
IDictionaryEnumerator id = reader.GetEnumerator();
foreach (DictionaryEntry d in reader)
{
if (d.Value == null)
resourceEntries.Add(d.Key.ToString(), "");
else
resourceEntries.Add(d.Key.ToString(), d.Value.ToString());
}
reader.Close();
}
//Modify resources here...
foreach (String key in data.Keys)
{
if (!resourceEntries.ContainsKey(key))
{
String value = data[key].ToString();
if (value == null) value = "";
resourceEntries.Add(key, value);
}
}
//Write the combined resource file
ResXResourceWriter resourceWriter = new ResXResourceWriter(path);
foreach (String key in resourceEntries.Keys)
{
resourceWriter.AddResource(key, resourceEntries[key]);
}
resourceWriter.Generate();
resourceWriter.Close();
}

How to put data from List<string []> to dataGridView

Try to put some data from List to dataGridView, but have some problem with it.
Currently have method, that return me required List - please see picture below
code
public List<string[]> ReadFromFileBooks()
{
List<string> myIdCollection = new List<string>();
List<string[]> resultColl = new List<string[]>();
if (chooise == "all")
{
if (File.Exists(filePath))
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
StreamReader sr = new StreamReader(fs);
string[] line = sr.ReadToEnd().Split(new string[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries);
foreach (string l in line)
{
string[] result = l.Split(',');
foreach (string element in result)
{
myIdCollection.Add(element);
}
resultColl.Add(new string[] { myIdCollection[0], myIdCollection[1], myIdCollection[2], myIdCollection[3] });
myIdCollection.Clear();
}
sr.Close();
return resultColl;
}
}
....
this return to me required data in requred form (like list from arrays).
After this, try to move it to the dataGridView, that already have 4 columns with names (because i'm sure, that no than 4 colums required) - please see pic below
Try to put data in to dataGridView using next code
private void radioButtonViewAll_CheckedChanged(object sender, EventArgs e)
{
TxtLibrary myList = new TxtLibrary(filePathBooks);
myList.chooise = "all";
//myList.ReadFromFileBooks();
DataTable table = new DataTable();
foreach (var array in myList.ReadFromFileBooks())
{
table.Rows.Add(array);
}
dataGridViewLibrary.DataSource = table;
}
But as result got error - "required more rows that exist in dataGridVIew", but accordint to what I'm see (pic above) q-ty of rows (4) equal q-ty of arrays element in List (4).
Try to check result by putting additional temp variables - but it's ok - please see pic below
Where I'm wrong? Maybe i use dataGridView not in correct way?
EDIT
example of file (simple csv)
11111, Author, Name, Categories
11341, Author1, Name1, Categories1
You need to add columns to your DataTable first before adding rows:
private void radioButtonViewAll_CheckedChanged(object sender, EventArgs e)
{
TxtLibrary myList = new TxtLibrary(filePathBooks);
myList.chooise = "all";
DataTable table = new DataTable();
//add columns first
table.Columns.Add("ID");
table.Columns.Add("Author");
table.Columns.Add("Caption");
table.Columns.Add("Categories");
//then add rows
foreach (var array in myList.ReadFromFileBooks()) {
table.Rows.Add(array);
}
dataGridViewLibrary.DataSource = table;
}
I think your code it's too complex. SImply, if you want see all data in the table from the file, you can do this
if (!System.IO.File.Exists("file.txt"))
return;
dgvDataGridView.ColumnCount = 4;
dgvDataGridView.Columns[0].HeaderCell.Value = "ID";
dgvDataGridView.Columns[1].HeaderCell.Value = "Author";
dgvDataGridView.Columns[2].HeaderCell.Value = "Caption";
dgvDataGridView.Columns[3].HeaderCell.Value = "Categories";
using (System.IO.StreamReader sr = new System.IO.StreamReader("file.txt"))
while (sr.Peek() > -1)
dgvDataGridView.Rows.Add(sr.ReadLine().Split(','));

Categories