Unexpected "," from StreamReader to StreamWriter - c#

I've tried a lot of things as well as research and asking friends, but can't seem to write a second line without a "," replacing the line. All I'd to do is have a single line for each item read in a separate file.
Each read file has several of these items:
2/20/2014 7:33:10 AM
OPERATOR: jason
FILE: C:\ax14\Setups\000062363106RH.prt
UNITS: english
TEST RESULT: Pass
CHANNEL 1
TEST TYPE: VELOCITY
RESULT: Pass
UPPER LIMIT: 0.2260
LOWER LIMIT: 0.2220
MAX THICKNESS: 2.0110
MIN THICKNESS: 1.0110
MEASURED VELOCITY: 0.2225
MEASURED THICKNESS: 1.5215
Id like to have the date and velocity line in one line like this:
"2/20/2014 7:33:10 AM, MEASURED VELOCITY: 0.2225"
and this is my problem
2/20/2014 7:33:10 AM,
,
,
,
,
,
,
,
,
,
,
,
, MEASURED VELOCITY: 0.2225
,
2/20/2014 7:52:28 AM,
,
,
,
,
,
,
,
,
,
,
,
, MEASURED VELOCITY: 0.2224
,
2/20/2014 7:58:46 AM,
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
namespace conApp
{
class Program
{
static void Main(string[] args)
{
String line;
try
{
using (StreamWriter sw = new StreamWriter("C:\\writetest\\writetest.txt"))
{
string mydirpath = "C:\\chat\\";
string[] txtFileList = Directory.GetFiles(mydirpath, "*.txt");
foreach (string txtName in txtFileList)
{
System.IO.StreamReader sr = new System.IO.StreamReader(txtName);
while ((line = sr.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(line))
{
String spart = ".prt";
String sam = " AM";
String spm = " PM";
String sresult = "TEST RESULT: ";
String svelocity = "MEASURED VELOCITY: ";
String part = "";
String date = "";
String result = "";
String velocity = "";
// sw.WriteLine(line);
if (line.Contains(sam))
{
date = line;
}
if (line.Contains(spm))
{
date = line;
}
if (line.Contains(spart))
{
part = line;
}
if (line.Contains(sresult))
{
result = line;
}
if (line.Contains(svelocity))
{
velocity = line;
}
int I = 2;
string[] x = new string[I];
x[0] = date;
x[1] = velocity;
sw.WriteLine(x[0] + "," + x[1]);
}
}
}
}
}
catch
{
}
}
}
}

Here is my suggestion for the full Main() trying to use as much from your code as possible. Declaring your vars outside the while statement you don't need to make it null.
EDIT- I forgot you said:
Each read file has several of these items
So added a few lines to handle that.
static void Main(string[] args)
{
string line;
try
{
using (StreamWriter sw = new StreamWriter("C:\\writetest\\writetest.txt"))
{
string mydirpath = "C:\\chat\\";
string[] txtFileList = Directory.GetFiles(mydirpath, "*.txt");
foreach (string txtName in txtFileList)
{
string spart = ".prt";
string sam = " AM";
string spm = " PM";
string sresult = "TEST RESULT: ";
string svelocity = "MEASURED VELOCITY: ";
string part = string.Empty;
string date = string.Empty;
string result = string.Empty;
string velocity = string.Empty;
using (StreamReader sr = new StreamReader(txtName))
{
while ((line = sr.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(line) && line.Trim().Length != 0)
{
if (line.Contains(sam) || line.Contains(spm))
{
// Every new date means a new record. If you already have data for a record, first write it.
if (date != string.Empty && velocity != string.Empty)
{
int I = 2;
string[] x = new string[I];
x[0] = date;
x[1] = velocity;
sw.WriteLine(x[0] + "," + x[1]);
}
// Then reset data to prepare it for a new record
part = string.Empty;
result = string.Empty;
velocity = string.Empty;
date = line;
}
if (line.Contains(spart))
{
part = line;
}
if (line.Contains(sresult))
{
result = line;
}
if (line.Contains(svelocity))
{
velocity = line;
}
}
}
}
// After last record you still have some data to write
if (date != string.Empty && velocity != string.Empty)
{
int I = 2;
string[] x = new string[I];
x[0] = date;
x[1] = velocity;
sw.WriteLine(x[0] + "," + x[1]);
}
}
}
}
catch
{
}
}

Only write the line once you have both values:
Then reset both values to null.
sw.WriteLine(x[0] + "," + x[1]);
Becomes:
if ( !String.IsNullOrWhitespace( date) && !String.IsNullOrWhitespace( velocity )
{
sw.WriteLine(x[0] + "," + x[1]);
date = null;
velocity = null;
}
As Blas mentioned you also need to move the variables outside the while statement:
String result = "";
String velocity = "";
while ((line = sr.ReadLine()) != null)

You can use this Regex Pattern to Achieve your goal :
(^.*?(?:AM|PM).*?)\r?\n.*(MEASURED VELOCITY:.*?$).*
And here's the code:
using (StreamWriter sw = new StreamWriter("C:\\writetest\\writetest.txt"))
{
string mydirpath = "C:\\chat\\";
string[] txtFileList = Directory.GetFiles(mydirpath, "*.txt");
Regex regex = new Regex("(^.*?(?:AM|PM).*?)\r?\n.*(MEASURED VELOCITY:.*?$).*",
RegexOptions.Multiline | RegexOptions.Singleline);
foreach (string txtName in txtFileList)
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(txtName))
{
string text = sr.ReadToEnd();
sw.WriteLine(regex.Replace(text, "$1, $2"));
}
}
}
Output for given file example:
2/20/2014 7:33:10 AM, MEASURED VELOCITY: 0.2225

Related

Accessing List values when having few strings inside a value

So I have the following code:
void ReadFromCsv()
{
using (var reader = new StreamReader(#"d:\test.csv", Encoding.Default))
{
List<string> listA = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
listA.Add(values[0]);
}
Console.WriteLine(listA);
}
}
which is reading from my csv file and an example of a line I get is:
50,2,10,201,10,9090339,24-OCT-21 09.38.38.679000 AM,123456789,24/10/2021 09:39:23,22/10/2021 09:39:37,Sm123456789-SM-20211031-VSR-000123.pdf,,,,,26/01/2022 13:08:58,,2,,0
first of all, why are there many commas around the end of the line?
second of all, what if I wanted to access the value "10" (which is the 5th value ) of that string line, is that possible?,
or going further, my task is to check for that 5th value and if its 5 for example, I'd want to take every row with 5thvalue=5 and create a csv for them, if 5thvalue=10 I want to create a csv for those records, and so on. but one task at a time, how do I access that value?
1: commas around the end of the line mean first item of lines is empty ""
2: you can get 5th value as below:
string _list = "50,2,10,201,10,9090339,24-OCT-21 09.38.38.679000 AM,123456789,24/10/2021 09:39:23,22/10/2021 09:39:37,Sm123456789-SM-20211031-VSR-000123.pdf,,,,,26/01/2022 13:08:58,,2,,0";
var fiveIndex = _list.Split(',')[4];
3:
then you can get list of lines that have a value of fiveIndex
var result =_list.Split(',').Select((v, i) => new { value = v, index = i }).Where(item => item.value == fiveIndex);
In your example, line 3 and line 5 have a value of 10(index=2, index=4). Then you can save these lines in csv file.
ended up doing:
string chargeMonth = DateTime.Now.ToString("yyyyMM");
var fileCreationDate = DateTime.Now.ToString("yyyyMMdd");
string fileCreationTime = DateTime.Now.ToString("HHmmss");
string constVal = "MLL";
string fileType = "HIYUV-CHEVRA";
string[] values;
string header, sumRow;
string line, compId;
string inputFile = "records.CSV";
Dictionary<string, System.IO.StreamWriter> outputFiles = new Dictionary<string, System.IO.StreamWriter>();
using (System.IO.StreamReader file = new System.IO.StreamReader("D:\\" + inputFile, Encoding.Default))
{
header = file.ReadLine();
while ((line = file.ReadLine()) != null)
{
values = line.Split(",".ToCharArray());
compId = values[3];
if (!outputFiles.ContainsKey(compId))
{
string outputFileName = constVal + "-" + fileType + "-" + (String.Format("{0:00000}", Int32.Parse(compId))) + "-" + chargeMonth + "-" + fileCreationDate + "-" + fileCreationTime + ".CSV";
outputFiles.Add(compId, new System.IO.StreamWriter("D:\\" + outputFileName));
outputFiles[compId].WriteLine(header);
}
outputFiles[compId].WriteLine(line);
}
}
foreach (System.IO.StreamWriter outputFile in outputFiles.Values)
{
outputFile.Close();
}
and the mission is done.

use streamreader find the specific user entry in the text file and display the 5th component in label

Data was passed from another form which containing a user entry, using Streamreader find the specific user entry in the text file and display the 5th component in the array.
in the login form, I passed the user entry: seow into this form, how do I make sure it displays 20, in label3?
in account.txt
seow 1111 wen 12345 20 50
user 1234 user1 12345 70 80
C# Code:
List<string> user = new List<string>();
private void Balance_Load(object sender, EventArgs e)
{
string username;
username = login.accountname;
StreamReader sr = new StreamReader("account.txt");
string line = "";
if (user.Contains(username))
{
while ((line = sr.ReadLine()) != null)
{
string[] components = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
label3.Text = string.Join(" ", components[5]);
}
sr.Close();
}
}
here is an example of I have tried
string path1 = AppDomainAppPath + "\\Subscribtion\\Subscribe.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path1);
var lines = File.ReadAllLines(path1);
for (var i = 0; i < lines.Length; i += 1)
{
// Process line
txtcollege.Value = lines[1];
txtplace.Value = lines[3];
}
file.Close();
ouput
ive madeit by changing the condition, thanks for the ideas
while ((line = sr.ReadLine()) != null)
{
string[] components = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
if( components.Contains(username))
{
curbal = string.Join(" ", components[5]);
label3.Text = curbal;
savbal = string.Join(" ", components[6]);
label5.Text = savbal;
}
}
sr.Close();

Find Specific String in Richtextbox C#

Hello I need to find a word in my Richtextbox I need to find the string "ERP Points and ERP Bonus Point"
Here's the contents of a Richboxtext:
https://pastebin.com/vdPQx5E4
Now here's my code:
string resultString = "";
foreach (string line in richTextBox2.Lines)
{
if (line.Contains("ERP Points") || line.Contains("ERP Bonus Point"))
{
resultString = richTextBox2.GetLineFromCharIndex(richTextBox2.Find("ERP", RichTextBoxFinds.MatchCase)).ToString();
var result = Regex.Replace(line, #"\D", "");
string output = Regex.Replace(line, "[^0-9]+", string.Empty);
MessageBox.Show(resultString);
MessageBox.Show(output);
FontArial = 1;
FontSize = Int32.Parse(output);
}
else
{
FontArial = 0;
FontSize = 0;
}
}
and here's my another version which gives me 153 and I don't know where the program gets that:
resultString = richTextBox2.GetLineFromCharIndex(richTextBox2.Find("ERP", RichTextBoxFinds.None)).ToString();
var result = Regex.Replace(line, #"\D", "");
string output = Regex.Replace(resultString, "[^0-9]+", string.Empty);
MessageBox.Show(resultString.ToString());
MessageBox.Show(output);
if (output != "")
{
FontArial = 1;
FontSize = Int32.Parse(output);
}
else
{
FontArial = 0;
FontSize = 0;
}

StreamWriter: Starting and ending on a specific line number

I would like to ask some tips and help on a reading/writing part of my C#.
Situation:
I have to read a CSV file; - OK
If the CSV file name starts with "Load_", I want to write on another CSV the data from line 2 to the last one;
If the CSV file name starts with "RO_", I want to write on 2 different CSVs, 1 with the line 1 to 4 and the other 4 to the last one;
What I have so far is:
public static void ProcessFile(string[] ProcessFile)
{
// Keeps track of your current position within a record
int wCurrLine = 0;
// Number of rows in the file that constitute a record
const int LINES_PER_ROW = 1;
int ctr = 0;
foreach (string filename in ProcessFile)
{
var sbText = new System.Text.StringBuilder(100000);
int stop_line = 0;
int start_line = 0;
// Used for the output name of the file
var dir = Path.GetDirectoryName(filename);
var fileName = Path.GetFileNameWithoutExtension(filename);
var ext = Path.GetExtension(filename);
var folderbefore = Path.GetFullPath(Path.Combine(dir, #"..\"));
var lineCount = File.ReadAllLines(#filename).Length;
string outputname = folderbefore + "output\\" + fileName;
using (StreamReader Reader = new StreamReader(#filename))
{
if (filename.Contains("RO_"))
{
start_line = 1;
stop_line = 5;
}
else
{
start_line = 2;
stop_line = lineCount;
}
ctr = 0;
while (!Reader.EndOfStream && ctr < stop_line)
{
// Add the text
sbText.Append(Reader.ReadLine());
// Increment our current record row counter
wCurrLine++;
// If we have read all of the rows for this record
if (wCurrLine == LINES_PER_ROW)
{
// Add a line to our buffer
sbText.AppendLine();
// And reset our record row count
wCurrLine = 0;
}
ctr++;
} // end of the while
}
int total_lenght = sbText.Length
// When all of the data has been loaded, write it to the text box in one fell swoop
using (StreamWriter Writer = new StreamWriter(dir + "\\" + "output\\" + fileName + "_out" + ext))
{
Writer.Write.(sbText.);
}
} // end of the foreach
} // end of ProcessFile
I was thinking about using the IF/ELSE: "using (StreamWriter Writer = new StreamWriter(dir + "\" + "output\" + fileName + "_out" + ext))" part. However, I am not sure how to pass, to StreamWriter, to only write from/to a specific line number.
Any Help is welcome! If I am missing some information, please, let me know (I am pretty new on stackoverflow).
Thank you.
Code is way too complicated
using System.Collections.ObjectModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication57
{
class Program
{
static void Main(string[] args)
{
}
public static void ProcessFile(string[] ProcessFile)
{
foreach (string filename in ProcessFile)
{
// Used for the output name of the file
var dir = Path.GetDirectoryName(filename);
var fileName = Path.GetFileNameWithoutExtension(filename);
var ext = Path.GetExtension(filename);
var folderbefore = Path.GetFullPath(Path.Combine(dir, #"..\"));
var lineCount = File.ReadAllLines(#filename).Length;
string outputname = folderbefore + "output\\" + fileName;
using (StreamWriter Writer = new StreamWriter(dir + "\\" + "output\\" + fileName + "_out" + ext))
{
int rowCount = 0;
using (StreamReader Reader = new StreamReader(#filename))
{
rowCount++;
string inputLine = "";
while ((inputLine = Reader.ReadLine()) != null)
{
if (filename.Contains("RO_"))
{
if (rowCount <= 4)
{
Writer.WriteLine(inputLine);
}
if (rowCount == 4) break;
}
else
{
if (rowCount >= 2)
{
Writer.WriteLine(inputLine);
}
}
} // end of the while
Writer.Flush();
}
}
} // end of the foreach
} // end of ProcessFile
}
}
You can use LINQ to Take and Skip lines.
public abstract class CsvProcessor
{
private readonly IEnumerable<string> processFiles;
public CsvProcessor(IEnumerable<string> processFiles)
{
this.processFiles = processFiles;
}
protected virtual IEnumerable<string> GetAllLinesFromFile(string fileName)
{
using(var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using(var reader = new StreamReader(stream))
{
var line = String.Empty;
while((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
protected virtual void ProcessFiles()
{
var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
foreach(var file in this.processFiles)
{
var fileName = Path.GetFileNameWithoutExtension(file);
var lines = GetAllLinesFromFile(file);
if(fileName.StartsWith("RO_", StringComparison.InvariantCultureIgnoreCase))
{
sb1.AppendLine(lines.Take(4)); //take only the first four lines
sb2.AppendLine(lines.Skip(4).TakeWhile(s => !String.IsNullOrEmpty(s))); //skip the first four lines, take everything else
}
else if(fileName.StartsWith("Load_", StringComparison.InvariantCultureIgnoreCase)
{
sb2.AppendLine(lines.Skip(1).TakeWhile(s => !String.IsNullOrEmpty(s)));
}
}
// now write your StringBuilder objects to file...
}
protected virtual void WriteFile(StringBuilder sb1, StringBuilder sb2)
{
// ... etc..
}
}

Union of million line urls in 2 files

File A B contains million urls.
1, go through the url in file A one by one.
2, extract subdomain.com (http://subdomain.com/path/file)
3, if subdomain.com exist file B, save it to file C.
Any quickest way to get file C with c#?
Thanks.
when i use readline, it have no much different.
// stat
DateTime start = DateTime.Now;
int totalcount = 0;
int n1;
if (!int.TryParse(num1.Text, out n1))
n1 = 0;
// memory
dZLinklist = new Dictionary<string, string>();
// read file
string fileName = openFileDialog1.FileName; // get file name
textBox1.Text = fileName;
StreamReader sr = new StreamReader(textBox1.Text);
string fullfile = File.ReadAllText(#textBox1.Text);
string[] sArray = fullfile.Split( '\n');
//IEnumerable<string> sArray = tool.GetSplit(fullfile, '\n');
//string sLine = "";
//while (sLine != null)
foreach ( string sLine in sArray)
{
totalcount++;
//sLine = sr.ReadLine();
if (sLine != null)
{
//string reg = "http[s]*://.*?/";
//Regex R = new Regex(reg, RegexOptions.Compiled);
//Match m = R.Match(sLine);
//if(m.Success)
int length = sLine.IndexOf(' ', n1); // default http://
if(length > 0)
{
//string urls = sLine.Substring(0, length);
dZLinklist[sLine.Substring(0,length)] = sLine;
}
}
}
TimeSpan time = DateTime.Now - start;
int count = dZLinklist.Count;
double sec = Math.Round(time.TotalSeconds,2);
label1.Text = "(" + totalcount + ")" + count.ToString() + " / " + sec + " = " + (Math.Round(count / sec,2)).ToString();
sr.Close();
I would go for using Microsoft LogParser for processing big files: MS LogParser. Are you limited to implement it in described way only?

Categories

Resources