有没有办法忽略文本文件中某些行的读取?

发布于 2024-09-19 15:50:55 字数 615 浏览 7 评论 0原文

我正在尝试读取 ac# 应用程序中的文本文件,但我不想读取前两行或最后一行。文件中有 8 行,所以实际上我只想读取第 3、4、5、6 和 7 行。 有什么办法可以做到这一点吗?

示例文件

_USE [Shelley's Other Database]  
CREATE TABLE db.exmpcustomers(  
fName varchar(100) NULL,  
lName varchar(100) NULL,  
dateOfBirth date NULL,  
houseNumber int NULL,  
streetName varchar(100) NULL  
) ON [PRIMARY]_  

编辑

好的,所以,我已经在我的代码中实现了 Callum Rogers 的答案,并且出于某种原因,它可以与我编辑的文本文件一起使用(我创建了一个文本文件,其中包含我不想使用省略的行)并且它确实做了它应该做的事情,但是每当我用原始文本文件(上面)尝试它时,它都会抛出异常。我在 DataGrid 中显示此信息,我认为这就是引发异常的地方。

有什么想法吗?

I'm trying to read in a text file in a c# application, but I don't want to read the first two lines, or the last line. There's 8 lines in the file, so effectivly I just want to read in lines, 3, 4, 5, 6 and 7.
Is there any way to do this?

example file

_USE [Shelley's Other Database]  
CREATE TABLE db.exmpcustomers(  
fName varchar(100) NULL,  
lName varchar(100) NULL,  
dateOfBirth date NULL,  
houseNumber int NULL,  
streetName varchar(100) NULL  
) ON [PRIMARY]_  

EDIT

Okay, so, I've implemented Callum Rogers answer into my code and for some reason it works with my edited text file (I created a text file with the lines I didn't want to use omitted) and it does exactly what it should, but whenever I try it with the original text file (above) it throws an exception. I display this information in a DataGrid and I think that's where the exception is being thrown.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

ら栖息 2024-09-26 15:50:55

罗杰斯的答案很好,我只是提供另一种方法。
试试这个,

List<string> list = new List<string>();
using (StreamReader reader = new StreamReader(FilePath))
{
    string text = "";
    while ((text = reader.ReadLine()) != null)
    {
        list.Add(text);
    }
    list.RemoveAt(0);
    list.RemoveAt(0);
 }

希望这有帮助

The Answer by Rogers is good, I am just providing another way of doing this.
Try this,

List<string> list = new List<string>();
using (StreamReader reader = new StreamReader(FilePath))
{
    string text = "";
    while ((text = reader.ReadLine()) != null)
    {
        list.Add(text);
    }
    list.RemoveAt(0);
    list.RemoveAt(0);
 }

Hope this helps

楠木可依 2024-09-26 15:50:55

为什么你想忽略前两行和最后一行?

根据您的文件的外观,您可能想要分析该行,例如查看第一个字符是否是注释符号,或者忽略所有内容,直到找到第一个空行等。

有时,硬编码“魔术”数字不是'这是个好主意。如果文件格式需要更改为包含 3 个标题行怎么办?

正如其他答案所表明的那样:没有什么可以阻止你用你读过的一行做你想做的事情,所以当然,你也可以忽略它。

编辑,现在您已经提供了文件示例:对于您的情况,我绝对不会使用硬编码数字方法。如果有一天 SQL 语句应该包含另一个字段,或者它出现在一行而不是 8 行中,该怎么办?

我的建议:立即读入整个字符串,然后分析它。最安全的方法是使用语法,但是如果你假设SQL语句永远不会变得更复杂,您可以使用正则表达式(仍然比使用行号等好得多):

string content = File.ReadAllText(filename);
Regex r = new Regex(@"CREATE TABLE [^\(]+\((.*)\) ON");
string whatYouWant = r.Match(content).Groups[0].Value;

Why do you want to ignore exactly the first two and the last line?

Depending on what your file looks like you might want to analyze the line, e.g. look at the first character whether it is a comment sign, or ignore everything until you find the first empty line, etc.

Sometimes, hardcoding "magic" numbers isn't such a good idea. What if the file format needs to be changed to contain 3 header lines?

As the other answers demonstrate: Nothing keeps you from doing what you ever want with a line you have read, so of course, you can ignore it, too.

Edit, now that you've provided an example of your file: For your case I'd definitely not use the hardcoded numbers approach. What if some day the SQL statement should contain another field, or if it appears on one instead of 8 lines?

My suggestion: Read in the whole string at once, then analyze it. Safest way would be to use a grammar, but if you presume the SQL statement is never going to be more complicated, you can use a regular expression (still much better than using line numbers etc.):

string content = File.ReadAllText(filename);
Regex r = new Regex(@"CREATE TABLE [^\(]+\((.*)\) ON");
string whatYouWant = r.Match(content).Groups[0].Value;
彼岸花似海 2024-09-26 15:50:55

为什么不直接使用 File.ReadAllLines() ,然后删除前 2 行和最后一行?对于如此小的文件,速度差异不会很明显。

string[] allLines = File.ReadAllLines("file.ext");
string[] linesWanted = new string[allLines.Length-3];
Array.Copy(allLines, 2, linesWanted, 0, allLines.Length-3);

Why not just use File.ReadAllLines() and then remove the first 2 lines and the last line? With such a small file speed differences will not be noticeable.

string[] allLines = File.ReadAllLines("file.ext");
string[] linesWanted = new string[allLines.Length-3];
Array.Copy(allLines, 2, linesWanted, 0, allLines.Length-3);
指尖上的星空 2024-09-26 15:50:55

如果您有一个包含文件流的 TextReader 对象,可以调用 ReadLine() 两次。

StreamReader 继承自 TextReader,它是抽象的。

非傻瓜证明示例:

using (var fs = new FileStream("blah", FileMode.Open))
using (var reader = new StreamReader(fs))
{
    reader.ReadLine();
    reader.ReadLine();

    // Do stuff.
}

If you have a TextReader object wrapping the filestream you could just call ReadLine() two times.

StreamReader inherits from TextReader, which is abstract.

Non-fool proof example:

using (var fs = new FileStream("blah", FileMode.Open))
using (var reader = new StreamReader(fs))
{
    reader.ReadLine();
    reader.ReadLine();

    // Do stuff.
}
合久必婚 2024-09-26 15:50:55
string filepath = @"C:\whatever.txt";
using (StreamReader rdr = new StreamReader(filepath))
{
    rdr.ReadLine();  // ignore 1st line
    rdr.ReadLine();  // ignore 2nd line
    string fileContents = "";
    while (true)
    {
        string line = rdr.ReadLine();
        if (rdr.EndOfStream)
            break;  // finish without processing last line
        fileContents += line + @"\r\n";
    }
    Console.WriteLine(fileContents);
}
string filepath = @"C:\whatever.txt";
using (StreamReader rdr = new StreamReader(filepath))
{
    rdr.ReadLine();  // ignore 1st line
    rdr.ReadLine();  // ignore 2nd line
    string fileContents = "";
    while (true)
    {
        string line = rdr.ReadLine();
        if (rdr.EndOfStream)
            break;  // finish without processing last line
        fileContents += line + @"\r\n";
    }
    Console.WriteLine(fileContents);
}
别挽留 2024-09-26 15:50:55

通用解决方案怎么样?

对我来说,第一步是枚举文件的行(已由 ReadAllLines,但是由于填充整个 string[] 数组,因此会产生性能成本; microsoft.com/en-us/library/dd383503.aspx" rel="nofollow noreferrer">ReadLines,但这仅在 .NET 4.0 中可用)。

实现这一点非常简单:

public static IEnumerable<string> EnumerateLines(this FileInfo file)
{
    using (var reader = file.OpenText())
    {
        while (!reader.EndOfStream)
        {
            yield return reader.ReadLine();
        }
    }
}

下一步是简单地跳过这个可枚举序列的前两行。使用 Skip 扩展程序非常简单方法。

最后一步是忽略可枚举序列的最后一行。这是实现此目的的一种方法:

public static IEnumerable<T> IgnoreLast<T>(this IEnumerable<T> source, int ignoreCount)
{
    if (ignoreCount < 0)
    {
        throw new ArgumentOutOfRangeException("ignoreCount");
    }

    var buffer = new Queue<T>();
    foreach (T value in source)
    {
        if (buffer.Count < ignoreCount)
        {
            buffer.Enqueue(value);
            continue;
        }

        T buffered = buffer.Dequeue();

        buffer.Enqueue(value);

        yield return buffered;
    }
}

好的,那么。将它们放在一起,我们有:

var file = new FileInfo(@"path\to\file.txt");
var lines = file.EnumerateLines().Skip(2).IgnoreLast(1);

测试输入(文件内容):

This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 10.

输出(Skip(2).IgnoreLast(1)):

This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.

How about a general solution?

To me, the first step is to enumerate over the lines of a file (already provided by ReadAllLines, but that has a performance cost due to populating an entire string[] array; there's also ReadLines, but that's only available as of .NET 4.0).

Implementing this is pretty trivial:

public static IEnumerable<string> EnumerateLines(this FileInfo file)
{
    using (var reader = file.OpenText())
    {
        while (!reader.EndOfStream)
        {
            yield return reader.ReadLine();
        }
    }
}

The next step is to simply skip the first two lines of this enumerable sequence. This is straightforward using the Skip extension method.

The last step is to ignore the last line of the enumerable sequence. Here's one way you could implement this:

public static IEnumerable<T> IgnoreLast<T>(this IEnumerable<T> source, int ignoreCount)
{
    if (ignoreCount < 0)
    {
        throw new ArgumentOutOfRangeException("ignoreCount");
    }

    var buffer = new Queue<T>();
    foreach (T value in source)
    {
        if (buffer.Count < ignoreCount)
        {
            buffer.Enqueue(value);
            continue;
        }

        T buffered = buffer.Dequeue();

        buffer.Enqueue(value);

        yield return buffered;
    }
}

OK, then. Putting it all together, we have:

var file = new FileInfo(@"path\to\file.txt");
var lines = file.EnumerateLines().Skip(2).IgnoreLast(1);

Test input (contents of file):

This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 10.

Output (of Skip(2).IgnoreLast(1)):

This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.
疯狂的代价 2024-09-26 15:50:55

您可以这样做:

var valid = new int[] { 3, 4, 5, 6, 7 };
var lines = File.ReadAllLines("file.txt").
    Where((line, index) => valid.Contains(index + 1));

或者相反:

var invalid = new int[] { 1, 2, 8 };
var lines = File.ReadAllLines("file.txt").
    Where((line, index) => !invalid.Contains(index + 1));

如果您正在寻找删除最后一个和前两个的通用方法,您可以使用这个:

var allLines = File.ReadAllLines("file.txt");
var lines = allLines
  .Take(allLines.Length - 1)
  .Skip(2);

但是从您的示例来看,您最好寻找以下字符串模式:你想从文件中读取。尝试使用正则表达式。

You can do this:

var valid = new int[] { 3, 4, 5, 6, 7 };
var lines = File.ReadAllLines("file.txt").
    Where((line, index) => valid.Contains(index + 1));

Or the opposite:

var invalid = new int[] { 1, 2, 8 };
var lines = File.ReadAllLines("file.txt").
    Where((line, index) => !invalid.Contains(index + 1));

If you're looking for a general way to remove the last and the first 2, you can use this:

var allLines = File.ReadAllLines("file.txt");
var lines = allLines
  .Take(allLines.Length - 1)
  .Skip(2);

But from your example it seems that you're better off looking for the string pattern that you want to read from the file. Try using regexes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文