I want to plot a graph from .csv file using second and fourth columns.
The data starts from the 9th row, I could skip 8 lines. But I want to access specific columns for plotting graph.
string ChosenFile = "";
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
ChosenFile = openFileDialog1.FileName;
char delimited = ',';
if (new FileInfo(ChosenFile).Length != 0)
{
try
{
var data = File.ReadLines(#ChosenFile).Skip(8)
.Select(line => line.Split(new Char[] { delimited }, StringSplitOptions.RemoveEmptyEntries))
.Select(chunk => chunk
.Select(x => Double.Parse(x, CultureInfo.InvariantCulture))
.ToArray());
series.Points.Clear();
foreach (var pair in data)
{
series.Points.AddXY(pair[0], pair[1]);
}
}
catch
{
logger.info("The file " + openFileDialog1.FileName + " cannot be opened because the content may be invalid or damaged.");
}
}
else logger.info(openFileDialog1.FileName + " is an empty file.");
}
This LINQ statement accesses only first two columns, but for my application I need to access data from second and fourth columns
What changes do I need to make in this statement to get these columns?
First let's fix your issue. Every column are in your data, you can access them by the index.
char delimited = ',';
var inputCSV = #"Skip it
Skip ita
Skip it
Col1,Col2,Foo,Bar
2.3,0.2,3.0,40.5
2.3,0.2,3.0,40.5
2.3,0.2,3.0,40.5";
var fileReadLinesMimic = inputCSV
.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
var data = fileReadLinesMimic
.Skip(4)
.Select(line => line.Split(new Char[] { delimited }, StringSplitOptions.RemoveEmptyEntries))
.Select(chunk =>
chunk.Select(x => Double.Parse(x, CultureInfo.InvariantCulture)
)
.ToArray());
foreach (var item in data)
{
Console.WriteLine($"Col1={item[0]}; Col2={item[1]}; Foo={item[2]}; Bar={item[3]};");
}
Related
I have a text file.
I need to add a newline after every new line from text and put every new line surrounded by "" or //.
My Output should be like this:
//Name Disengagement point//
//Description Automated test case to record
disengagement point and force-travel characteristic needed for the
point.//
//StartRecording ForceTravel//
//UserInteraction Please, start attempting to shift the gear to 1st gear.//
//Capture DisengagementPoint UserInput == 1 PressClutch 1 UserInput == 1//
//UserInteraction Please, shift the gear to neutral.//
//ReleaseClutch 100 ForceTravel == LimitReleased//
The method for reading text file:
if (!File.Exists(measurementPath))
{
string[] readText = File.ReadAllLines(measurementPath);
foreach (string s in readText)
{
script = s.Replace(" ", " // ");
char[] separator = new char[] { ' ' };
String[] fields = s.Split(separator);
You can use File.ReadLines, LINQ + String.Format and File.WriteAllLines:
var newLines = File.ReadLines(measurementPath)
.Select(line => String.Format("//{0}//", line))
.ToList();
File.WriteAllLines(measurementPath, newLines);
public static List<string> items = new List<string>() { "a","b","c","d","e" };
I am trying to change each of those from loading a file and replacing with their current inventory.
if (File.Exists("darColItems.txt") == true)
{
char c = ',';
StreamReader st = new StreamReader("darColItems.txt");
temp = st.ReadToEnd().ToCharArray();
foreach (c in temp)
{
}
st.Close();
}
Edit: Taking a file such as: iron,bronze,gold,diamond,iron and taking each name and place it into the list for each spot.
File.txt: "string1","string2","string3","string4","string5"
Startup of program:
List inventory (current):
"a","b","c","d","e"
Load inventory....
List inventory (final):
"string1","string2","string3","string4","string5"
Assuming that you actually want to replace all items in the list with all items in the file in the order of occurence and the delimiter is comma. You could use String.Split:
items = File.ReadAllText("path").Split(new [] { ',' }, StringSplitOptions.None).ToList();
If you have quotes around the words in the file which you want to remove, you can use String.Trim:
items = File.ReadAllText("path")
.Split(new char[] { ',' }, StringSplitOptions.None)
.Select(s => s.Trim('"', ' ')) // remove quotes + spaces at the beginning and end
.ToList();
//keep filename in a constant/variable for easy reuse (better, put it in a config file)
const string SourceFile = "darColItems.txt";
//what character separates data elements (if the elements may contain this character you may instead want to look into a regex; for now we'll keep it simple though, & assume that's not the case
const char delimeter = ',';
//here's where we'll store our values
var values = new List<string>();
//check that our input file exists
if (File.Exists(SourceFile))
{
//using statement ensures file is closed & disposed, even if there's an error mid-process
using (var reader = File.OpenText(SourceFile))
{
string line;
//read each line until the end of file (at which point the line read will be null)
while ((line = reader.ReadLine()) != null)
{
//split the string by the delimiter (',') and feed those values into our list
foreach (string value in line.Split(delimiter)
{
values.Add(value);
}
}
}
}
I am getting data from a CSV file through my Web Api with this code
private List<Item> items = new List<Item>();
public ItemRepository()
{
string filename = HttpRuntime.AppDomainAppPath + "App_Data\\items.csv";
var lines = File.ReadAllLines(filename).Skip(1).ToList();
for (int i = 0; i < lines.Count; i++)
{
var line = lines[i];
var columns = line.Split('$');
//get rid of newline characters in the middle of data lines
while (columns.Length < 9)
{
i += 1;
line = line.Replace("\n", " ") + lines[i];
columns = line.Split('$');
}
//Remove Starting and Trailing open quotes from fields
columns = columns.Select(c => { if (string.IsNullOrEmpty(c) == false) { return c.Substring(1, c.Length - 2); } return string.Empty; }).ToArray();
var temp = columns[5].Split('|', '>');
items.Add(new Item()
{
Id = int.Parse(columns[0]),
Name = temp[0],
Description = columns[2],
Photo = columns[7]
});
}
}
But the CSV file returned data with special characters instead of an apostrophe.
For example in the CSV file the are values such as There’s which should be "There's" or "John’s" which should be "John's".
This ’ is there instead of an apostrophe.
How do I get rid of this to just show my apostrophe.
This kind of data is being returned in
Name = temp[0],
Description = columns[2],
You can use the HttpUtility.HtmlDecode to convert the characters. Here's an example:
var withEncodedChars = "For example in the CSV file the are values such as There’s which should be There's or John’s which should be John's. This ’ is there instead of an apostrophe.";
Console.WriteLine(HttpUtility.HtmlDecode(withEncodedChars));
If you run this in a console app it outputs:
For example in the CSV file the are values such as There's which should be There's or John's which should be John's. This ' is there instead of an apostrophe.
I'd like to write some data to a CSV file using C#.
Here's my code at the moment :
int length = readData.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Length;
List<List<string>> dataList = new List<List<string>>();
foreach (string line in readData.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
{
List<string> partsLine = new List<string>();
partsLine.AddRange(line.Split('\t'));
dataList.Add(partsLine);
}
So, I'm splitting all the data in lines.
Then I split each line with '\t' separator, and add each part of the line in a list.
And at the end I have a list containing all the lists of split lines.
So the list looks like :
List1 {txt1, txt 2} = first line
List2 {txt3, txt 4, txt 5, txt 6} = second line
List3 {txt7, txt 8, txt 9, txt 10} = third line
List4 {txt 11, txt 12} etc.
All of the lists don't have the same lenght as you can see.
What I'd like to do is writing all the lists to a CSV file.
Each list would fill a row and a certain number of columns, depending of the lenght of the list (i.e. txt1 should be (row1, col1), txt2 should be (row1, col2), txt3 should be (row2, col1), txt4 would be (row2, col2)...).
How can I do that ?
Thanks
List<List<String>> dataList = new List<List<string>>();
//...
const char SEPARATOR = ",";
using (StreamWriter writer = new StreamWriter("file.csv"))
{
dataList.ForEach(line =>
{
var lineArray = line.Select(c =>
c.Contains(SEPARATOR) ? c.Replace(SEPARATOR.ToString(), "\\" + SEPARATOR) : c).ToArray();
writer.WriteLine(string.Join(SEPARATOR, lineArray));
});
}
CSV format by itself does not intend to be formatted with rows with variable columns length.
CSV (Comma separated values) is just "table like" format, so if you want to follow its convention, you have to first define all possible columns and fill rows one-by-one, so several cells on several rows will remain empty.
If this is not what you want, just choose your custom format.
I'm coming back on this topic because I realized that the .csv format won't suit my needs.
I need to plot some charts using all the data that I have, and I read that .csv files don't support chart integration. So, instead of exporting my List<List<string>> to .csv, I'd like to export it to an .xls file.
I tried to do it just by changing the type of the file to .xls in the StreamWriter parameter, but the data doesn't fit like in the .csv. What should I change in my code ?
// Write data to a .csv file
private void WriteToCSV(string data)
{
int length = data.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Length;
// List of lists containing each line split by part
List<List<string>> dataList = new List<List<string>>();
List<string> valuesA = new List<string>();
// Building the list
foreach (string line in data.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
{
List<string> partsLine = new List<string>();
partsLine.AddRange(line.Split('\t'));
dataList.Add(partsLine);
}
const string separator = ";";
// Writing the list to the .csv file
try
{
using (StreamWriter writer = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\output.xls", false))
{
dataList.ForEach(line =>
{
var lineArray = line.Select(c => c.Contains(separator) ? c.Replace(separator.ToString(), "\\" + separator) : c).ToArray();
writer.WriteLine(string.Join(separator, lineArray));
});
}
}
catch (Exception ex)
{
Console.WriteLine("Error while writing data to .csv file (" + ex.Message + ")");
}
On the picture you can see the previous format (.csv on the right) and the new one (.xls on the left).
http://imageshack.us/photo/my-images/850/cax.png/
I have 4 text files in one folder and a pattern.txt to compare these text files..In pattern.txt i have
insert
update
delete
drop
I need to compare this text file with those four text files and if these patterns matches any line in that text files i have to write those lines in another log file...i had read those files using linq..i need to compare those files and write in a text file with line number..here is my code
var foldercontent = Directory.GetFiles(pathA)
.Select(filename => File.ReadAllText(filename))
.Aggregate(new StringBuilder(),
(sb, s) => sb.Append(s).Append(Environment.NewLine),
sb => sb.ToString());
var pattern = File.ReadAllLines(pathB).Aggregate(new StringBuilder(),
(sb, s) => sb.Append(s).Append(Environment.NewLine),
sb => sb.ToString());
using (var dest = File.AppendText(Path.Combine(_logFolderPath, "log.txt")))
{
//dest.WriteLine("LineNo : " + counter.ToString() + " : " + "" + line);
}
EDIT
I have already used c# to compare two text files but i need this in linq
while ((line = file.ReadLine()) != null)
{
if (line.IndexOf(line2, StringComparison.CurrentCultureIgnoreCase) != -1)
{
dest.WriteLine("LineNo : " + counter.ToString() + " : " + " " + line.TrimStart());
}
counter++;
}
file.BaseStream.Seek(0, SeekOrigin.Begin);
counter = 1;
There might be a simpler solution, but this is at least working if you really want to use LINQ:
var foldercontent = Directory.GetFiles(pathA)
.Select(filename => new
{
Filename = filename,
Lines = File.ReadAllLines(filename)
})
.SelectMany(file => file.Lines.Select((line, idx) => new
{
LineNumber = idx + 1,
Text = line,
FileName = file.Filename
}));
var pattern = File.ReadAllLines(pathB);
var result = from fileLine in foldercontent
where pattern.Any(p => fileLine.Text.IndexOf(p, StringComparison.CurrentCultureIgnoreCase) != -1)
select fileLine;
foreach (var match in result)
{
System.Diagnostics.Debug.WriteLine("File: {0} LineNo: {1}: Text: {2}", match.FileName, match.LineNumber, match.Text);
}
Or if you want, you can combine that into one LINQ query (but thats not very readable i think):
var result = from fileLine in (Directory.GetFiles(pathA)
.Select(filename => new
{
Filename = filename,
Lines = File.ReadAllLines(filename)
})
.SelectMany(file => file.Lines.Select((line, idx) => new
{
LineNumber = idx + 1,
Text = line,
FileName = file.Filename
})))
where File.ReadAllLines(pathB).Any(p => fileLine.Text.IndexOf(p, StringComparison.CurrentCultureIgnoreCase) != -1)
select fileLine;
Since I'm a linq enthusiast, and will sometimes use a tool when it's inappropriate (I agree with #juharr about using grep or something similar for this situation) here is a possible version for you.
static IEnumerable<string> CreateMatchesLog(string patternFilePath, string pathToSearch)
{
string logTemplate = "File {0}, Line: {1}, Pattern: {2}";
DirectoryInfo di = new DirectoryInfo(pathToSearch);
var patternlines = File.ReadAllLines(patternFilePath);
var fileslines = di.EnumerateFiles().Select(fi => File.ReadAllLines(fi.FullName).Select((line, i) => new {fi.FullName, line, i}));
return from filelines in fileslines
from pattern in patternlines
from fileline in filelines
where fileline.line.Contains(pattern)
select String.Format(logTemplate, fileline.FullName, fileline.i + 1, pattern);
}
Then you'd write the output of this function to a file.
using (StreamWriter sw = new StreamWriter("log.txt", true))
{
foreach (var log in CreateMatchesLog("pattern.txt", #"c:\test"))
{
sw.WriteLine(log);
}
}
I've set append to true in the StreamWriter, because I assume you don't want to lose the contents of the file each time you run the programme.
It looks pretty inefficient (not tested that aspect), but it uses linq and lambdas up the wazoo!