Why do I only get results from my first txt? - c#

I am trying to read & use all lines from txt files. With a method I iterate through them asinc, and I try to get the data. My problem is, the output looks like it only contains the data from the first txt file. I just cant find where the problem is. I would appreciate any help.
Here's my code:
string[] files = Directory.GetFiles("C:/DPS-EDPWB05/forlogsearch", "*", SearchOption.AllDirectories);
//data I need from the txts
List<string> num = new List<string>();
List<string> date = new List<string>();
List<string> time = new List<string>();
List<string> sip = new List<string>();
List<string> csmethod = new List<string>();
List<string> csuristem = new List<string>();
List<string> csuriquery = new List<string>();
List<string> sport = new List<string>();
List<string> csusername = new List<string>();
List<string> cip = new List<string>();
List<string> csuseragent = new List<string>();
List<string> csreferer = new List<string>();
List<string> scstatus = new List<string>();
List<string> scsubstatus = new List<string>();
List<string> cswin32status = new List<string>();
List<string> timetaken = new List<string>();
int x = 0;
int y = 0;
int i = 0;
int filesCount = 0;
string v = "";
//Taking the data from the Log, getting a list of string[]
//items with the lines from the txts
List<string[]> lines = new List<string[]>();
while (i < files.Length)
{
lines.Add(ReadAllLinesAsync(files[i]).Result);
i++;
}
//Trying to get the data from the string[]s
do
{
string line;
int f = 0;
string[] linesOfTxt = lines[filesCount];
do
{
line = linesOfTxt[f];
string[] splittedLine = { };
splittedLine = line.Split(' ', 15, StringSplitOptions.None);
y = splittedLine.Count();
if (y == 15)
{
num.Add(x.ToString());
date.Add(splittedLine[0]);
time.Add(splittedLine[1]);
sip.Add(splittedLine[2]);
csmethod.Add(splittedLine[3]);
csuristem.Add(splittedLine[4]);
csuriquery.Add(splittedLine[5]);
sport.Add(splittedLine[6]);
csusername.Add(splittedLine[7]);
cip.Add(splittedLine[8]);
csuseragent.Add(splittedLine[9]);
csreferer.Add(splittedLine[10]);
scstatus.Add(splittedLine[11]);
scsubstatus.Add(splittedLine[12]);
cswin32status.Add(splittedLine[13]);
timetaken.Add(splittedLine[14]);
x++;
}
f++;
} while (f < linesOfTxt.Length);
filesCount++;
}
while (filesCount < files.Count());
After all this I group these and stuff but that happens AFTER the lists of data i need are filled - so the problem must be here somewhere. Also, my asinc reader (I found here on stackoverflow):
public static Task<string[]> ReadAllLinesAsync(string path)
{
return ReadAllLinesAsync(path, Encoding.UTF8);
}
public static async Task<string[]> ReadAllLinesAsync(string path, Encoding encoding)
{
var lines = new List<string>();
// Open the FileStream with the same FileMode, FileAccess
// and FileShare as a call to File.OpenText would've done.
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultBufferSize, DefaultOptions))
using (var reader = new StreamReader(stream, encoding))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
lines.Add(line);
}
}
return lines.ToArray();
}

There are several problems with the example code, thou I'm unsure what is responsible for the actual issue.
Instead of writing your own ReadAllLinesAsync, just use File.ReadAllLinesAsync
You should in general avoid .Result since this is a blocking operation, and this has the potential to cause deadlocks. In this case you should just call the synchronous version, File.ReadAllLines, instead.
When possible, use foreach or for loops. They make it much easier to see if your code is correct, and avoids spreading the loop logic over multiple lines.
As far as I can see, you are processing each line identically, so you should be able to just merge all lines from all files by using List<string> lines and AddRange
Instead of keeping 15 different lists of properties, a more common approach would be to store one list of objects of a class with 15 different properties.
Whenever you need to store data, you should seriously consider using an existing serialization format, like json, xml, csv, protobuf etc. This lets you use existing, well tested, libraries for writing and reading data and converting it to your own types.

Related

How to split CSV file

"0.0.0.0,""0.255.255.255"",""ZZ"""
"1.0.0.0,""1.0.0.255"",""AU"""
"1.0.1.0,""1.0.3.255"",""CN"""
"1.0.4.0,""1.0.7.255"",""AU"""
"1.0.8.0,""1.0.15.255"",""CN"""
"1.0.16.0,""1.0.31.255"",""JP"""
"1.0.32.0,""1.0.63.255"",""CN"""
"1.0.64.0,""1.0.127.255"",""JP"""
"1.0.128.0,""1.0.255.255"",""TH"""
"1.1.0.0,""1.1.0.255"",""CN"""
"1.1.1.0,""1.1.1.255"",""AU"""
"1.1.2.0,""1.1.63.255"",""CN"""
"1.1.64.0,""1.1.127.255"",""JP"""
"1.1.128.0,""1.1.255.255"",""TH"""
İN EXCEL
0.0.0.0,"0.255.255.255","ZZ"
1.0.0.0,"1.0.0.255","AU"
1.0.1.0,"1.0.3.255","CN"
1.0.4.0,"1.0.7.255","AU"
1.0.8.0,"1.0.15.255","CN"
1.0.16.0,"1.0.31.255","JP"
1.0.32.0,"1.0.63.255","CN"
1.0.64.0,"1.0.127.255","JP"
1.0.128.0,"1.0.255.255","TH"
1.1.0.0,"1.1.0.255","CN"
1.1.1.0,"1.1.1.255","AU"
1.1.2.0,"1.1.63.255","CN"
1.1.64.0,"1.1.127.255","JP"
1.1.128.0,"1.1.255.255","TH"
1.2.0.0,"1.2.2.255","CN"
1.2.3.0,"1.2.3.255","AU"
1.2.4.0,"1.2.127.255","CN"
1.2.128.0,"1.2.255.255","TH"
1.3.0.0,"1.3.255.255","CN"
1.4.0.0,"1.4.0.255","AU"
1.4.1.0,"1.4.127.255","CN"
1.4.128.0,"1.4.255.255","TH"
How can split this CSV file.
For example 0.0.0.0 0.255.255.255 ZZ for first row and how can add datagridview with 3columns
You can do it via the following way..
using System.IO;
static void Main(string[] args)
{
using(var reader = new StreamReader(#"C:\test.csv"))
{
List<string> listA = new List<string>();
List<string> listB = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(','); // or whatever yur get by reading that file
listA.Add(values[0]);
listB.Add(values[1]);
}
}
}
A CSV file is either a Tab delimited or a Comma delimited file. That said; you have to read the file line by line and then separate the values available in a line based on the delimiter character. The first line usually appears in a CSV file is usually the headers which you can use in order to produce a KeyValue pair to make your collection more efficient. For example:
Dictionary<int, Dictionary<String, String>> values = new Dictionary<int, Dictionary<String,String>>();
using(FileStream fileStream = new FileStream(#"D:\MyCSV.csv", FileMode.Open, FileAccess.Read, FileShare.Read)) {
using(StreamReader streamReader = new StreamReader(fileStream)){
//You can skip this line if there is no header
// Then instead of Dictionary<String,String> you use List<String>
var headers = streamReader.ReadLine().Split(',');
String line = null;
int lineNumber = 1;
while(!streamReader.EndOfStream){
line = streamReader.ReadLine().split(',');
if(line.Length == headers.Length){
var temp = new Dictionary<String, String>();
for(int i = 0; i < headers.Length; i++){
// You can remove '"' character by line[i].Replace("\"", "") or through using the Substring method
temp.Add(headers[i], line[i]);
}
values.Add(lineNumber, temp);
}
lineNumber++;
}
}
In case the data structure of your CSV is constant and it will not change in the future, you can develop a strongly typed data model and get rid of the Dictionary type. This approach will be more elegant and more efficient.
First of all, your CSV lines are surrounded by quotes. Is it copy/paste mistake? If not, you will need to sanitize the file to a valid CSV file.
You can try Cinchoo ETL - an open source library to load the CSV file to datatable, then you can assign it to your DataGridView source.
I'll show you both approach, how to handle
Valid CSV: (test.csv)
0.0.0.0,"0.255.255.255","ZZ"
1.0.0.0,"1.0.0.255","AU"
1.0.1.0,"1.0.3.255","CN"
1.0.4.0,"1.0.7.255","AU"
1.0.8.0,"1.0.15.255","CN"
1.0.16.0,"1.0.31.255","JP"
1.0.32.0,"1.0.63.255","CN"
1.0.64.0,"1.0.127.255","JP"
1.0.128.0,"1.0.255.255","TH"
1.1.0.0,"1.1.0.255","CN"
1.1.1.0,"1.1.1.255","AU"
1.1.2.0,"1.1.63.255","CN"
1.1.64.0,"1.1.127.255","JP"
1.1.128.0,"1.1.255.255","TH"
Read CSV:
using (var p = new ChoCSVReader("test.csv"))
{
var dt = p.AsDataTable();
//Assign dt to DataGridView
}
Next approach
Invalid CSV: (test.csv)
"0.0.0.0,""0.255.255.255"",""ZZ"""
"1.0.0.0,""1.0.0.255"",""AU"""
"1.0.1.0,""1.0.3.255"",""CN"""
"1.0.4.0,""1.0.7.255"",""AU"""
"1.0.8.0,""1.0.15.255"",""CN"""
"1.0.16.0,""1.0.31.255"",""JP"""
"1.0.32.0,""1.0.63.255"",""CN"""
"1.0.64.0,""1.0.127.255"",""JP"""
"1.0.128.0,""1.0.255.255"",""TH"""
"1.1.0.0,""1.1.0.255"",""CN"""
"1.1.1.0,""1.1.1.255"",""AU"""
"1.1.2.0,""1.1.63.255"",""CN"""
"1.1.64.0,""1.1.127.255"",""JP"""
"1.1.128.0,""1.1.255.255"",""TH"""
Read CSV:
using (var p = new ChoCSVReader("Sample6.csv"))
{
p.SanitizeLine += (o, e) =>
{
string line = e.Line as string;
if (line != null)
{
line = line.Substring(1, line.Length - 2);
line = line.Replace(#"""""", #"""");
}
e.Line - line;
};
var dt = p.AsDataTable();
//Assign dt to DataGridView
}
Hope it helps.

CSV Column into ASP DropdownList

I am trying to populate an ASP dropdownlist with a column from a CSV. I was able to do it with the below code, however, it shows duplicates since another one of the columns' values are all unique (so using .distinct() is no good). Here is an example of my CSV entries:
env,app,srvrole,servers
Dev,appname1,web,server01
Production,appname1,cache,server02
The servers column is always unique.
Here is my code:
var collection_of_objects =
(from line in File.ReadAllLines("\\server\\shares\\App\\Farms.csv").Skip(1)
let parts = line.Split(',')
select new
{
env = parts[0],
app = parts[1],
srvrole = parts[2],
servers = parts[3],
}
).ToList();
dropdown_app.DataSource = collection_of_objects.Distinct();
dropdown_app.DataTextField = "app";
dropdown_app.DataBind();
srvrole.DataSource = collection_of_objects.Distinct();
srvrole.DataTextField = "srvrole";
srvrole.DataBind();
I also attempted to use Streamreader and output to a Datatable, however, I could not assign the Datatable to the datasource of the dropdown. TYIA
I was able to figure it out using streamreader. If there are any easier ways to do this, I am all ears!
protected void Page_Load(object sender, EventArgs e)
{
List<string> environment = new List<String>();
List<string> application = new List<String>();
List<string> serverrole = new List<String>();
List<string> servers = new List<String>();
ReadCSV(environment, application, serverrole, servers);
string[] envlist = environment.ToArray();
string[] applist = application.ToArray();
string[] srvrolelist = serverrole.ToArray();
string[] serverlist = servers.ToArray();
dropdown_app.DataSource = applist.Skip(1).Distinct();
dropdown_app.DataBind();
srvrole.DataSource = srvrolelist.Skip(1).Distinct();
srvrole.DataBind();
}
public static void ReadCSV(List<string> environment, List<string> application, List<string> serverrole, List<string> servers)
{
StreamReader reader = new StreamReader(File.OpenRead(#"\\server\shares\App\Reference\Farms.csv"));
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (!String.IsNullOrWhiteSpace(line))
{
string[] values = line.Split(',');
if (values.Length >= 4)
{
environment.Add(values[0]);
application.Add(values[1]);
serverrole.Add(values[2]);
servers.Add(values[3]);
}
}
}
}

Separate string from list C#

I have list of string and each of that strings in list look like this: sim_pin: 1234. List have 24 strings, and I wanna to get each of that strings, separate string where separator will be : ( : and space), and save to list only that part who is right from separator.
EDIT:
Here is my code
string url = #"E:\Sims.log";
public static IEnumerable<DiverGate> GetData(string url)
{
Stream stream = File.Open(url, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (StreamReader sr = new StreamReader(stream))
{
string str = sr.ReadToEnd();
string[] lines = Regex.Split(str, "\r\n");
List<string> lista = new List<string>();
foreach (string line in lines)
{
lista.Add(line);
}
List<string> header = lista.GetRange(0, 23);
//I stop here and im out of idea
}
}
Something like this should work:
where input is your original list of strings
List<string> output = new List<string>();
input.ForEach(x=> output.Add(x.Split(new[] {": "},StringSplitOptions.None).Last()));
var List1 = new List<string>{"sim_pin: 1234", "sim_pin: 2345", "sim_pin: 3456"};
var List2 = new List<string>();
foreach (var s in List1) {
var ns = s.Split(':')[1].TrimStart(' ');
List2.Add(ns);
}
try this code:
for ( int i =0; i< yourList.Count(); i++) {
string s = yourList[i];
int i = s.indexOf(":");
s = s.Substring (i);
yourList.Insert(i, s);
}

Reading file with C#

I want to read php text file using c#. The file looks like:
2.20:2.20:2.20:2.20:2.20:
2012-07-12:2012-07-11:2012-07-10:2012-07-09:2012-07-08:
I would like to get all lines to listboxes. In real situation there is six lines, but first I should have read these two lines. My code:
void web_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
int i;
string price_line = "";
string date_line = "";
List<decimal> prices = new List<decimal>();
List<string> dates = new List<string>();
using (var reader = new StreamReader(e.Result))
{
price_line = reader.ReadLine();
date_line = reader.ReadLine();
string[] bit_1 = price_line.Split(':');
string[] bit_2 = date_line.Split(':');
for (i = 0; i < 2; i++)
{
prices.Add(decimal.Parse(bit_1[i]));
dates.Add(bit_2[i]);
}
listBox1.ItemsSource = prices;
listBox2.ItemsSource = dates;
}
}
catch
{
MessageBox.Show("Can't read!");
}
}
Now I get "NullException". How to fix this?
EDIT:
What's about:
using (StreamReader reader = new StreamReader(e.Result))
{
List<string> lines = new List<string>();
while (!reader.EndOfStream)
lines.Add(reader.ReadLine());
string prices = lines.First().Split(':');
List<decimal> listPrices = new List<decimal>();
List<string> listDates = lines.Last().Split(':').ToList();
foreach(string s in prices)
listPrices.Add(double.Parse(s));
listBox1.ItemsSource = listPrices;
listBox2.ItemsSource = listDates;
}
You should check if e.Result, listBox1 and listBox2 aren't null.

C# reading a file into a 2-D array

my project is using txt file as db, each line in the txt file will be something like "abc,cdf,ghi,zkl"
now i am reading line by line from the text file and split the line into an array data[] by ","
but i want to put this array into another main array called datas[], so i can store this datas[] array in memory for the whole class to use,
i dont want to fix datas[] array size as the txt file records will be growing.
what can i do in this case? i tried to make datas[] as arraylist then stored data[] array in it , but error showed.
class user
{
ArrayList userDatas = new ArrayList();
public user()
{
readUsers();
}
public void readUsers()
{
string line;
StreamReader sr = new StreamReader("user.txt", System.Text.Encoding.Default);
while ((line = sr.ReadLine()) != null)
{
ArrayList temp = new ArrayList();
string[] rc = line.Split('|');
for (int i = 0; i < rc.Length; i++)
{
temp.Add(rc[i]);
}
userDatas.Add(temp);
}
}
public bool login(string ic, string password)
{
for (int i = 0; i < userDatas.Count; i++)
{
ArrayList temp = userDatas;
if ((temp[1] == ic) && (temp[2] == password))
{
return true;
}
}
return false;
}
}
Of course if you don't mind being a little cute you should be able to do it with one line coutesy of LINQ:
string[][] LinesSplitByComma = File.ReadAllLines("file path").Select(s => s.Split(',')).ToArray();
Instead of ArrayList, use List<string> for temp and List<string[]> for userDatas.
When you're done filling them, you can convert to an array by simply calling userDatas.ToArray()
Also, your error might be here:
ArrayList temp = userDatas;
if ((temp[1] == ic) && (temp[2] == password))
{
return true;
}
You're not first checking to make sure temp has 3 or more elements before referencing indexes 1 and 2. Also, why are you creating temp only to assign it to userDatas? Why not just say:
if (userDatas.Count() >= 3 && (userDatas[1] == ic) && (userDatas[2] == password))
return true;
EDIT
As requested, here's my original code, though you already have much of it written, but here it is (you're code didn't show up at first):
StreamReader reader = new StreamReader();
List<string[]> datas = new List<string[]>();
List<string> data = new List<string>();
string line;
while (!reader.EndOfStream) {
line = reader.ReadLine();
datas.Add(line.Split(','));
}
string[] datas_array = datas.ToArray();

Categories

Resources