7

What I have to do is read only the second line in a .txt file and save it as a string, to use later in the code.

The file name is "SourceSetting". In line 1 and 2 I have some words

For line 1, I have this code:

string Location;
StreamReader reader = new StreamReader("SourceSettings.txt");
{
    Location = reader.ReadLine();
}
ofd.InitialDirectory = Location;

And that works out great but how do I make it so that it only reads the second line so I can save it as for example:

string Text
Dayan
  • 7,634
  • 11
  • 49
  • 76
Christoph Bethge
  • 217
  • 1
  • 5
  • 20

5 Answers5

16

You can skip the first line by doing nothing with it, so call ReadLine twice:

string secondLine:
using(var reader = new StreamReader("SourceSettings.txt"))
{
    reader.ReadLine(); // skip
    secondLine = reader.ReadLine();  
}

Another way is the File class that has handy methods like ReadLines:

string secondLine = File.ReadLines("SourceSettings.txt").ElementAtOrDefault(1);

Since ReadLines also uses a stream the whole file must not be loaded into memory first to process it. Enumerable.ElementAtOrDefault will only take the second line and don't process more lines. If there are less than two lines the result is null.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
7

Update I'd advice to go with Tim Schmelter solution.

When you call ReadLine - it moves the carret to next line. So on second call you'll read 2nd line.

string Location;
using(var reader = new StreamReader("SourceSettings.txt"))
{
    Location = reader.ReadLine(); // this call will move caret to the begining of 2nd line.
    Text = reader.ReadLine(); //this call will read 2nd line from the file
}
ofd.InitialDirectory = Location;

Don't forget about using.

Or an example how to do this vi ReadLines of File class if you need just one line from file. But solution with ElementAtOrDefault is the best one as Tim Schmelter points.

var Text = File.ReadLines(@"C:\Projects\info.txt").Skip(1).First()

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.

So it doesn't read all lines into memory in comparison with ReadAllLines.

Community
  • 1
  • 1
Artiom
  • 7,694
  • 3
  • 38
  • 45
  • Hmmm... but what will `Skip` return? Will it force the full enumeration so that it can determine all the lines after the first? I would guess it does, so you would still end up reading the whole file – musefan Sep 10 '15 at 11:21
  • `Skip` returns new IEnumerable which will skip first element. It won't force reader to read all lines from the file except you'll do smth like: `File.ReadLines(@"C:\Projects\info.txt").Skip(1).ToArray()`. From MSDN: The immediate return value is an object that stores all the information that is required to perform the action. – Artiom Sep 10 '15 at 11:24
  • Yeah, that makes sense – musefan Sep 10 '15 at 11:25
3

The line could be read using Linq as follows.

var SecondLine = File.ReadAllLines("SourceSettings.txt").Skip(1).FirstOrDefault();
Codor
  • 17,447
  • 9
  • 29
  • 56
  • I find the downvote suprising. Is it because of the necessity to read the entire file? – Codor Sep 10 '15 at 11:07
  • Same for me) Not aware why downvote since it's valid – Artiom Sep 10 '15 at 11:08
  • Yeah, the downvote is as you expected, for reading the whole file. OP wants just the second line, and you suggest reading all the lines? Could be a 50 million line file :/ Then adding the `Skip` is likely even worse as I would assume it copies the whole array except the first line. It's just a bad recommendation, for something so simple – musefan Sep 10 '15 at 11:16
  • 2
    @musefan: that assumption is not correct even if `ElementAtOrdefault` is more appropriate. `Skip` doesn't copy anything because it is using deferred execution. But of course `File.ReadLines` is much better here. – Tim Schmelter Sep 10 '15 at 11:24
  • @TimSchmelter Thanks for [ElementAtOrDefault](https://msdn.microsoft.com/en-us/library/vstudio/bb494386%28v=vs.100%29.aspx) of which I wasn't aware. – Codor Sep 10 '15 at 11:28
  • 1
    @TimSchmelter: Yeah, Artion informed me, as I'm obvious not feeling in the mood to check these things myself. So `Skip` isn't an issue. But still, this is bad code, especially if you already know why it's bad (you could be forgiven for not realizing the issue). Why 2 people have upvoted it I don't know. Just cause something works it doesn't mean it is good – musefan Sep 10 '15 at 11:28
2
private string GetLine(string filePath, int line)
{
    using (var sr = new StreamReader(filePath))
    {
        for (int i = 1; i < line; i++)
             sr.ReadLine();
        return sr.ReadLine();
     }
 }

Hope this will help :)

Artiom
  • 7,694
  • 3
  • 38
  • 45
Awn Ali
  • 1,361
  • 1
  • 17
  • 31
  • That is actually a useful function, not sure why it was downvoted, I mean, as a standalone function then you might want to put validation checking in there, but as a concept I think it's a good answer – musefan Sep 10 '15 at 11:37
  • It's useful but already available in the framework: `File.ReadLines(path).ElementAtOrDefault(line)`. The method above continues calling `ReadLine` even if it already returned `null` since it's at the end of the stream. – Tim Schmelter Jan 23 '21 at 10:47
-1

If you know that your second line is unique, because it contains a specific keyword that does not appear anywhere else in your file, you also could use linq, the benefit is that the "second" line could be any line in future.

             var myLine = File.ReadLines("SourceSettings.txt")
            .Where(line => line.Contains("The Keyword"))
            .ToList();
Bgl86
  • 727
  • 8
  • 20
  • OP has mentioned nothing about searching for a keyword. Just a nice simple question about getting the second line... and 'in the future' the keyword might not be unique anymore, so no point trying to cater for what-ifs in this scenario – musefan Sep 10 '15 at 11:23
  • Yes but he was talking about a kind of settings file, that imho could grow or change over time, why not adding some flexibility to your code? – Bgl86 Sep 10 '15 at 11:25
  • 1
    But you are making assumptions about things that have not been asked. You don't know if there is a keyword so the answer doesn't help. You should comment if you want to clarify something or offer such a suggestion. This isn't a place to just put 'answers that might be relevant'. You should answer each question directly – musefan Sep 10 '15 at 11:32