Explaining codes - c#

Hi can anyone explain these lines of codes, I need to understand how it works in order to proceed with what I am doing
if (e.Error == null){
Stream responseStream = e.Result;
StreamReader responseReader = new StreamReader(responseStream);
string response = responseReader.ReadToEnd();
string[] split1 = Regex.Split(response, "},{");
List<string> pri1 = new List<string>(split1);
pri1.RemoveAt(0);
string last = pri1[pri1.Count() - 1];
pri1.Remove(last);
}

// Check if there was no error
if (e.Error == null)
{
// Streams are a way to read/write information from/to somewhere
// without having to manage buffer allocation and such
Stream responseStream = e.Result;
// StreamReader is a class making it easier to read from a stream
StreamReader responseReader = new StreamReader(responseStream);
// read everything that was written to a stream and convert it to a string using
// the character encoding that was specified for the stream/reader.
string response = responseReader.ReadToEnd();
// create an array of the string by using "},{" as delimiter
// string.Split would be more efficient and more straightforward.
string[] split1 = Regex.Split(response, "},{");
// create a list of the array. Lists makes it easier to work with arrays
// since you do not have to move elements manually or take care of allocations
List<string> pri1 = new List<string>(split1);
pri1.RemoveAt(0);
// get the last item in the array. It would be more efficient to use .Length instead
// of Count()
string last = pri1[pri1.Count() - 1];
// remove the last item
pri1.Remove(last);
}
I would use a LinkedList instead of List if the only thing to do was to remove the first and last elements.

It's reading the response stream as a string, making the assumption that the string consists of sequences "{...}" separated by commas, e.g.:
{X},{Y},{Z}
then splits the string on "},{", giving an array of
{X
Y
Z}
then removes the first brace from the first element of the array ( {X => X ) and the end brace from the last element of the array ( Z} => Z).

From what I can see, it is reading from a stream that could have came from TCP.
It reads the whole chunk of data, then separate the chunk using the delimiter },{.
So if you have something like abc},{dec , it will be placed into split1 array with 2 values, split1 [0]=abc , split1 [1]=dec.
After that, it basically remove the 1st and the last content

It is processing an error output.
It received a stream from the e (I guess it is an exception), reads it.
It looks something like :
""{DDD},{I failed},{Because},{There was no signal}{ENDCODE}
It splits it into different string, and removes to fist and last entries (DDD, ENDCODE)

Related

Got wrong data while split file into arrays

I have file contains two lines and each line contains 200 fields and I would like to split it into arrays
using (StreamReader sr = File.OpenText(pathSensorsCalc))
{
string s = String.Empty;
while ((s = sr.ReadLine()) == null) { };
String line1 = sr.ReadToEnd();
String line2 = sr.ReadToEnd();
CalcValue[0] = new String[200];
CalcValue[1] = new String[200];
CalcValue[0] = line1.Split(' ');
CalcValue[1] = line2.Split(' ');
}
After the code above, CalcValue[1] is empty and CalcValue[0] contains data of the second line (instad of the first one). Any ideas?
When using
sr.ReadToEnd()
, you are reading to the end of your input stream. That means, after the first call of
String line1 = sr.ReadToEnd()
your stream is already at the last position. Replace your ReadToEnd() call with ReadLine() calls. That should work.
In the Windows OS, a new line is represented by \r\n. So you should not split the lines by spaces (" ").
Which means you should use another overload of the Split method - Split(char[], StringSplitOptions). The first argument is the characters you want to split by and the second is the options. Why do you need the options? Because if you split by 2 continuous characters you get an empty element.
So now it is easy to understand what this code does and why:
line1.Split (new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);

Reading a specific line from a csv file and letting the line vary

I need to take 1 line from a CSV file and need the line number to be able to vary. I can make an int, double, string etc. and I can change the value from an outer program easily but I don't know how make a file reader script take one of those as the input for the line number.
string GetLine(string lineresults, int LineNumber)
{
using (var sr = new StreamReader(lineresults)) {
for (int i = 1; i < line; i++)
sr.ReadLine();
return sr.ReadLine();
}
}
And I get errors on the GetLine part for semicolons and closeparens expected
If you want random access you can read all lines and store them in an array, so File.ReadAllLines (remember that your variable LineNumber starts at 0):
string[] allLines = File.ReadAllLines(pathToFile);
string line = allLines[LineNumber]; // error if less lines, check allLines.Length
Another more efficient approach is to use File.ReadLines which lazy loads the lines, then use Enumerable.ElementAt or ElementAtOrDefault to access the line number:
var lines = File.ReadLines(pathToFile);
string line = lines.ElementAtOrDefault(LineNumber); // null if there are less lines
It is worth noting that it reads the file until the line number or the end of the file was reached.
MSDN:
The ReadLines and ReadAllLines methods differ as follows: When you use
ReadLines, you can start enumerating the collection of strings before
the whole collection is returned; when you use ReadAllLines, you must
wait for the whole array of strings be returned before you can access
the array. Therefore, when you are working with very large files,
ReadLines can be more efficient
As #Alex K commented simply read all the lines into an Array and then get the line you are after.
var lines = System.IO.File.ReadAllLines( filename);
var line = lines[ lineIndex ];
This NuGet package is super-duper helpful for working with CSVs. You can grab individual lines from it, and individual columns by either name or index. Check out info here:
[Josh Close - CsvHelper][1]

Reading a specific line with StreamReader

I have a problem with the stream reader. i want to read from a text file just one line.
I want a specific line, like the seventh line. and i don't know how to.
it's a function or something like that ? like file.ReadLine(number 7) ?
The simplest approach would probably be to use LINQ combined with File.ReadLines:
string line = File.ReadLines("foo.txt").ElementAt(6); // 0-based
You could use File.ReadAllLines instead, but that would read the whole file even if you only want an early one. If you need various different lines of course, it means you can read them in one go. You could write a method to read multiple specific lines efficiently (i.e. in one pass, but no more than one line at a time) reasonably easily, but it would be overkill if you only want one line.
Note that this will throw an exception if there aren't enough lines - you could use ElementAtOrDefault if you want to handle that without any exceptions.
If you want to read line by number it's better to use
string line = File.ReadLines(fileName).Skip(N).FirstOrDefault();
Thus you will avoid reading all lines from file, and you'll read lines only until you get line you need. If you need several lines, then it's better to read all lines to array, and then get your lines from that array:
string[] lines = File.ReadAllLines(fileName);
if (lines.Count() > N)
line = lines[N];
if you want to specific line by using StreamReader.
Suppose you have a data Line1,Line2,Line3,Line4 in text files.
Every time you call "ReadLine" method it will increase 1 line.
That mean you can write you own function and passing your parmeter to function.
You can do it by.
string l1, l2, l3, l4;
StreamReader sr = new StreamReader(sourcePath);
l1 = sr.Readline(); // Line 1
l2 = sr.Readline(); // Line 2
l3 = sr.Readline(); // Line 3
public string StreamReadLine(string sourcepath, int lineNum)
{
int index = lineNum;
string strLine = "N/A";
StreamReader sr = new StreamReader(sourcepath);
try
{
for (var i = 0; i <= index; i++)
{
strLine = sr.ReadLine();
if (i == index)
break;
i += 1;
}
}
catch (Exception ex)
{
strLine = ex.ToString();
}
return strLine;
}

How to read a file into a string with CR/LF preserved?

If I asked the question "how to read a file into a string" the answer would be obvious. However -- here is the catch with CR/LF preserved.
The problem is, File.ReadAllText strips those characters. StreamReader.ReadToEnd just converted LF into CR for me which led to long investigation where I have bug in pretty obvious code ;-)
So, in short, if I have file containing foo\n\r\nbar I would like to get foo\n\r\nbar (i.e. exactly the same content), not foo bar, foobar, or foo\n\n\nbar. Is there some ready to use way in .Net space?
The outcome should be always single string, containing entire file.
Are you sure that those methods are the culprits that are stripping out your characters?
I tried to write up a quick test; StreamReader.ReadToEnd preserves all newline characters.
string str = "foo\n\r\nbar";
using (Stream ms = new MemoryStream(Encoding.ASCII.GetBytes(str)))
using (StreamReader sr = new StreamReader(ms, Encoding.UTF8))
{
string str2 = sr.ReadToEnd();
Console.WriteLine(string.Join(",", str2.Select(c => ((int)c))));
}
// Output: 102,111,111,10,13,10,98,97,114
// f o o \n \r \n b a r
An identical result is achieved when writing to and reading from a temporary file:
string str = "foo\n\r\nbar";
string temp = Path.GetTempFileName();
File.WriteAllText(temp, str);
string str2 = File.ReadAllText(temp);
Console.WriteLine(string.Join(",", str2.Select(c => ((int)c))));
It appears that your newlines are getting lost elsewhere.
This piece of code will preserve LR and CR
string r = File.ReadAllText(#".\TestData\TR120119.TRX", Encoding.ASCII);
The outcome should be always single string, containing entire file.
It takes two hops. First one is File.ReadAllBytes() to get all the bytes in the file. Which doesn't try to translate anything, you get the raw data in the file so the weirdo line-endings are preserved as-is.
But that's bytes, you asked for a string. So second hop is to apply Encoding.GetString() to convert the bytes to a string. The one thing you have to do is pick the right Encoding class, the one that matches the encoding used by the program that wrote the file. Given that the file is pretty messed up if it contains \n\r\n sequences, and you didn't document anything else about the file, your best bet is to use Encoding.Default. Tweak as necessary.
You can read the contents of a file using File.ReadAllLines, which will return an array of the lines. Then use String.Join to merge the lines together using a separator.
string[] lines = File.ReadAllLines(#"C:\Users\User\file.txt");
string allLines = String.Join("\r\n", lines);
Note that this will lose the precision of the actual line terminator characters. For example, if the lines end in only \n or \r, the resulting string allLines will have replaced them with \r\n line terminators.
There are of course other ways of acheiving this without losing the true EOL terminator, however ReadAllLines is handy in that it can detect many types of text encoding by itself, and it also takes up very few lines of code.
ReadAllText doesn't return carriage returns.
This method opens a file, reads each line of the file, and then adds each line as an element of a string. It then closes the file. A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. The resulting string does not contain the terminating carriage return and/or line feed.
From MSDN - https://msdn.microsoft.com/en-us/library/ms143368(v=vs.110).aspx
This is similar to the accepted answer, but wanted to be more to the point. sr.ReadToEnd() will read the bytes like is desired:
string myFilePath = #"C:\temp\somefile.txt";
string myEvents = String.Empty;
FileStream fs = new FileStream(myFilePath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
myEvents = sr.ReadToEnd();
sr.Close();
fs.Close();
You could even also do those in cascaded using statements. But I wanted to describe how the way you write to that file in the first place will determine how to read the content from the myEvents string, and might really be where the problem lies. I wrote to my file like this:
using System.Reflection;
using System.IO;
private static void RecordEvents(string someEvent)
{
string folderLoc = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!folderLoc.EndsWith(#"\")) folderLoc += #"\";
folderLoc = folderLoc.Replace(#"\\", #"\"); // replace double-slashes with single slashes
string myFilePath = folderLoc + "myEventFile.txt";
if (!File.Exists(myFilePath))
File.Create(myFilePath).Close(); // must .Close() since will conflict with opening FileStream, below
FileStream fs = new FileStream(myFilePath, FileMode.Append);
StreamWriter sr = new StreamWriter(fs);
sr.Write(someEvent + Environment.NewLine);
sr.Close();
fs.Close();
}
Then I could use the code farther above to get the string of the contents. Because I was going further and looking for the individual strings, I put this code after THAT code, up there:
if (myEvents != String.Empty) // we have something
{
// (char)2660 is ♠ -- I could have chosen any delimiter I did not
// expect to find in my text
myEvents = myEvents.Replace(Environment.NewLine, ((char)2660).ToString());
string[] eventArray = myEvents.Split((char)2660);
foreach (string s in eventArray)
{
if (!String.IsNullOrEmpty(s))
// do whatever with the individual strings from your file
}
}
And this worked fine. So I know that myEvents had to have the Environment.NewLine characters preserved because I was able to replace it with (char)2660 and do a .Split() on that string using that character to divide it into the individual segments.

C# StreamReader save to Array with separator

I´ve got a text file with tabulator separated data. What I need in my C# application is that I read one line from the text file and save them to an array, separate them at the each \t. Then I do the same thing with the next row.
My code:
StreamReader sr = new StreamReader(dlg.FileName);
string s = sr.ReadLine();
Now, I already tried to write the line into an array but that doesn´t work. Does anyone one how to manage this?
Use the Split method to create an Array of the line
string[] parts = s.Split('\t');
See Documentation on Split() here
foreach (string line in System.IO.File.ReadAllLines(dlg.FileName))
{
var myArray = line.Split('\t');
}
s.Split('\t') will split your string by the tabulator character, and create a string[] with appropriate length.
Ammending your example code:
StreamReader sr = new StreamReader(dlg.FileName);
string s = sr.ReadLine();
var items = s.Split('\t');
In the end, items contains an array of strings that represent the characters between the tabs. The tabs are not included in the array. The array may contain empty elements (for the case of two consecutive tabs).
Use the String.Split() method: http://msdn.microsoft.com/en-us/library/b873y76a.aspx
StreamReader reader = new StreamReader("input.txt");
string[] content = reader.ReadToEnd().Replace("\n","").Split('\t');
if you want to keep New Line's than
string[] content = reader.ReadToEnd().Split('\t');
In the example below, items will be a String[] containing each line of text's values. It will be overwritten with each iteration so you'll want to do something with it inside the loop. Save it to a larger collection, write it to a file, etc...
StreamReader sr = new StreamReader(dlg.FileName);
while (sr.Peek() >= 0) {
var line = sr.ReadLine();
var items = line.Split(new Char[] { '\t' });
}
If the file contains only one line, then use:
string[] myArray = s.Split('\t');

Categories