Read specified line from external text file - c#

I'm using C# and writing a Windows Form application for Windows 7 or Windows 8.
I need to know how to get my app to read a specific line which should be assigned to a specific text box or combo box.
This is the code I have so far.
using (StreamReader QNARead = new StreamReader(TestPath))
if (QNARead.Peek() >= 0)
{
string Line1 = QNARead.ReadLine();
QuestionText1.Text = Line1;
string Line2 = QNARead.ReadLine();
QuestionText2.Text = Line2;
string Line3 = QNARead.ReadLine();
AlternativesList1.Items.Add(Line3);
}
But with this method I'll have to read a lot of lines, because the line could be the 500th in the text file. (I do know the exact line number, eg. 54).

I used once this to read a specific line in a text file:
string filename = "test.txt";
if (File.Exists(filename))
{
string[] lines = File.ReadAllLines(filename);
Console.WriteLine(lines[5]);
}
where 5 can be replaced with any line number (zero based).

Since a file is just a list of bytes, you need to know how far into it to read, to get the line you want.
Unless the lines are fixed (or predictable) lengths, or you have some kind of separate index, you need to read every line up to the one you want. From a code point of view you can make this fairly tidy, for example in Framework 4.0:
string line54 = File.ReadLines(FileName).Skip(53).Take(1).First();
Note that at this point, you're not taking advantage of reading the earlier lines being skipped over, so a more efficient way would be to keep reading in a loop until you reach the last line needed.

Related

Delete specific row from File

I have this little project in C# where I am manipulating with files. Now my task is that I have to delete specific rows from files.
For example my file looks like this:
1-this is the first line
2-this is the second line
3-this is the third line
4-this is the fourth line
Now how can I keep only the first two rows and delete only the last two rows?
Note- this is how I read the file from my local machine:
string[] lines = File.ReadAllLines(#"C:\Users\admin\Desktop\COMMANDS.dat");
I have tried something like this but I think it's not so "efficient"
string text = File.ReadAllText(#"C:\Users\admin\Desktop\COMMANDS.dat");
text = text.Replace(lines[2], "");
text = text.Replace(lines[3], "");
File.WriteAllText(#"C:\Users\admin\Desktop\COMMANDS.dat", text);
So this actually does the job, it replaces the lines by string with an empty character but when I take a look at the file, I don't want to have 4 lines there, even though 2 of them are real strings and the other two are just empty lines... Can I manage to do this in another way?
Try replacing the newline character with an empty string:
string text = File.ReadAllText(#"C:\Users\admin\Desktop\COMMANDS.dat");
text = text.Replace(lines[2], "").Remove(Environment.NewLine, "");
text = text.Replace(lines[3], "").Remove(Environment.NewLine , "");
File.WriteAllText(#"C:\Users\admin\Desktop\COMMANDS.dat", text);
If my answer is useful, please mark it as accepted, and upvote it.
async Task Example()
{
var inputLines = await File.ReadAllLinesAsync("path/to/file.txt");
var outputLines = inputLines.Where((l, i) => i < 2);
await File.WriteAllLinesAsync("target/file.txt", outputLines);
}
What it does
Read data but not as one string but as a collection of lines
Create a new collection containing only the lines you want in your output
Write the filtered lines
Notes:
This example is not optimized for memory usage (because we read all lines and for larger files, e.g. multiple GB, this will fail). See existing answers for memory optimized version) - but: It's totally fine to do it this way if you know you have just a few k lines. (and it's faster)
Try not to "modify" strings. This will always create a copy and needs a lot of memory.
In this "Linq style" (functional) approach, we should treat data as immutable. That means: we have one variable that represents the input file and one variable that represents the result. We use declarative Linq to describe how the output should look like. "output is input where the filter index < 2 matches" instead of "if xy remove line" in an imperative style.

Shift text file rows by one deleting the first line

how to Shift text file rows by one after deleting a particular line based on condition xyz=true for that particular line. I want to use C#.
using (StreamWriter writer = new StreamWriter(file))
{
while ((line = rows[rowIndex++]) != null)
{
if( line contains xyz )// i know the logic to find this;
{
delete this line and shift all below lines one up;
}
}
}
A simple way to do this for small files (files which can be completely loaded into memory) is to use File.ReadAllLines() to get a string[] of the lines. With this, you can loop through the array of strings and test each one to determine if it should be written to the new file or not.
A similar question came up recently here C# Delete line i text file if it is different than specific term
If you're writing the output to a new file, you don't need to worry about moving all the later lines up, removing the entire line will also remove the line ending characters.
Hope this helps

Get partcular information from text file (C#)

I need a c# program which can split strings and copy some particular informations into another file.
I've a text file like this:
BRIDGE.V2014R6I1.SOFT
icem.V4R12I2.SOFT
mygale.V4R1I1.SOFT,patch01_MAJ_APL.exe
photoshop.V2014R10I1.SOFT
rhino.V5R0I1.SOFT,patch01_Update_Files.exe
TSFX.V2R3I2.SOFT,patch01_corrections.exe,patch02_clock.exe,patch03_correction_tri_date.exe,patch04_gestion_chemins_unc.exe
and I need only some of these information into another file as below :
BRIDGE,SOFT
ICEM,SOFT
MYGALE,SOFT
PHOTOSHOP,SOFT
any helps pls :)
As I don't know, wether your text file is always like that, I can only provide a specific answer. First of all you have to, as ThatsEli pointed out, split the string at the point:
var splitted = inputString.Split(".");
Now it seems as though your second (zero based index) item has the irrelevant information with a comma splitted from the relevant. So all you have to do is to build together the zeroth and the second, while the second only has the first part before the comma:
var res = $"{splitted[0]},{splitted[2].Split(",")[0]}";
However, you seem to want your result in uppercase:
var resUpper = res.ToUpper();
But actually this only works as long as you have a perfect input file - otherwise you have to check, wether it actually has that many items or you'll get an IndexOutOfRange exception.
Actually I'm not sure wether you know how to read/write from/to a file, so I'll provide examples on this as well.
Read
var path = #"Your\Path\To\The\Input\File";
if (!File.Exists(path))
{
Console.WriteLine("File doesn't exist! If you're using a console, otherwise use another way to print error messages");
return;
}
var inputString = File.ReadAllText(path);
Write
var outputPath = #"your\Output\Path";
if(!File.Exists(outputPath))
{
Console.WriteLine("You know what to put here");
return;
}
File.WriteAllText(outputPath, inputString);
I would split the string and create a new file with parts of the array you got from the split.
You can split a string with eg. Split(".");
And then e.g. create a new string stringname = splitstring[0] + "," + splitstring[2]
That would add the first and third part back together.
That would apply to your first line.

Read First and Last Line in a File

I have a need to read - read the first and last lines of a log file in a .NET 4.5 application
, that is.
The log file has timestamps on every line and I want to find the youngest (first line) and oldest (last line) timestamps. This isn't a difficult task but I'm wondering if there's a clever way of doing it.
Currently the implementation looks like this (I actually need the second line of the log file because the first line is blank, hence the Skip()):
string firstLine = File.ReadLines(logFile).Skip(1);
string lastLine = File.ReadLines(logFile).Last();
Can there be any improvements to this very simple code?
Read once in an IEnumerable<string>, and then use that for second and last line.
var lines = File.ReadLines(logFile);
string firstLine = lines.Skip(1);
string lastLine = lines.Last();
In your current code you are doing the reading twice, If you expect the file to be modified between first read and second, then you have to read the file twice.
Well the most obvious solution File.ReadLines has been found already.
An alternative, in case of big files, could be:
ReverseLineReader class from here:
https://stackoverflow.com/a/452945/2254877

Reading line by line

I have a program that generates a plain text file. The structure (layout) is always the same. Example:
Text File:
LinkLabel
"Hello, this text will appear in a LinkLabel once it has been
added to the form. This text may not always cover more than one line. But will always be surrounded by quotation marks."
240, 780
So, to explain what is going on in that file:
Control
Text
Location
And when a button on the Form is clicked, and the user opens one of these files from the OpenFileDialog dialog, I need to be able to Read each line. Starting from the top, I want to check to see what control it is, then starting on the second line I need to be able to get all text inside the quotation marks (regardless of whether is is one line of text or more), and on the next line (after the closing quotation mark), I need to extract the location (240, 780)... I have thought of a few ways of going about this but when I go to write it down and put it to practice, it doesn't make much sense and end up figuring out ways that it won't work.
Has anybody ever done this before? Would anybody be able to provide any help, suggestions or advice on how I'd go about doing this?
I have looked up CSV files but that seems too complicated for something that seems so simple.
Thanks
jase
You could use a regular expression to get the lines from the text:
MatchCollection lines = Regex.Matches(File.ReadAllText(fileName), #"(.+?)\r\n""([^""]+)""\r\n(\d+), (\d+)\r\n");
foreach (Match match in lines) {
string control = match.Groups[1].Value;
string text = match.Groups[2].Value;
int x = Int32.Parse(match.Groups[3].Value);
int y = Int32.Parse(match.Groups[4].Value);
Console.WriteLine("{0}, \"{1}\", {2}, {3}", control, text, x, y);
}
I'll try and write down the algorithm, the way I solve these problems (in comments):
// while not at end of file
// read control
// read line of text
// while last char in line is not "
// read line of text
// read location
Try and write code that does what each comment says and you should be able to figure it out.
HTH.
You are trying to implement a parser and the best strategy for that is to divide the problem into smaller pieces. And you need a TextReader class that enables you to read lines.
You should separate your ReadControl method into three methods: ReadControlType, ReadText, ReadLocation. Each method is responsible for reading only the item it should read and leave the TextReader in a position where the next method can pick up. Something like this.
public Control ReadControl(TextReader reader)
{
string controlType = ReadControlType(reader);
string text = ReadText(reader);
Point location = ReadLocation(reader);
... return the control ...
}
Of course, ReadText is the most interesting one, since it spans multiple lines. In fact it's a loop that calls TextReader.ReadLine until the line ends with a quotation mark:
private string ReadText(TextReader reader)
{
string text;
string line = reader.ReadLine();
text = line.Substring(1); // Strip first quotation mark.
while (!text.EndsWith("\"")) {
line = reader.ReadLine();
text += line;
}
return text.Substring(0, text.Length - 1); // Strip last quotation mark.
}
This kind of stuff gets irritating, it's conceptually simple, but you can end up with gnarly code. You've got a comparatively simple case:one record per file, it gets much harder if you have lots of records, and you want to deal nicely with badly formed records (consider writing a parser for a language such as C#.
For large scale problems one might use a grammar driven parser such as this: link text
Much of your complexity comes from the lack of regularity in the file. The first field is terminated by nwline, the second by delimited by quotes, the third terminated by comma ...
My first recomendation would be to adjust the format of the file so that it's really easy to parse. You write the file so you're in control. For example, just don't have new lines in the text, and each item is on its own line. Then you can just read four lines, job done.

Categories

Resources