简体   繁体   English

我想从文件中检索数据

[英]I want to retrieve Data from file

When I enter Id card number or phone number, it should fetch the line from file if Id or phone number matches. 当我输入身份证号码或电话号码时,如果身份证号码或电话号码匹配,则应该从文件中获取该行。 I have tried the following code but it fetches the id number & not the whole line with this Id card number eg name, address, phone number. 我已经尝试了以下代码,但是它使用此Id卡号(例如姓名,地址,电话号码)获取ID号而不是整行。

string path=@"C:\Users\Precision\Desktop\testing\data.txt";
Console.WriteLine("Enter CNIC or Phone No");
string check = Console.ReadLine();
using (StreamReader sr = new StreamReader(path))
{
    string lines = sr.ReadToEnd();

    if (lines.Contains(check))
    {
        dirList.Add(lines);
        Console.WriteLine("Data Found Against {0}", check);

        string stringToSearch = check;
        string[] liness = File.ReadAllLines(path);
        foreach (string line in liness)
        {
            if (line.Contains(stringToSearch))
            {
                Console.WriteLine(line);
            }
        }
    }
    else
    {
        Console.WriteLine("No Data Found");
    }
}

Example Data: 示例数据:

Id Card No :123456789 Phone No :545454 First Name :asasa Surname:asasa House:sas Street:as Sector:as City:asasas Country :asasa

1st you should simplify your code, eg actually you're reading the same file twice ( sr.ReadToEnd() , File.ReadAllLines(path) ). 首先你应该简化你的代码,例如实际上你正在读两次相同的文件( sr.ReadToEnd()File.ReadAllLines(path) )。 Then you should try to output ALL the lines (or better: inspect them in a debugger) to check if the data is actually in the format you expect. 然后你应该尝试输出所有行(或者更好:在调试器中检查它们)以检查数据是否实际上是你期望的格式。 And additionally you have to decide if your entered search string check should actually be searched case sensitive or not. 此外,您还必须确定您输入的搜索字符串检查是否应该实际上是否区分大小写。

The logic will depend on how you delimit each data item. 逻辑将取决于您如何划分每个数据项。
If each item is separated by a new line (ie \\r\\n ) then you should iterate as follows: 如果每个项目由一个新行分隔(即\\r\\n ),那么您应该按如下方式迭代:

public List<string> SearchList()
{
    var path = @"C:\Users\Precision\Desktop\testing\data.txt";

    Console.WriteLine("Enter CNIC or Phone No");
    var check = Console.ReadLine();

    var dirList = new List<string>();

    using (StreamReader sr = new StreamReader(path))
    {
        var lines = sr.ReadToEnd()
                      .Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

        foreach (var line in lines)
        {
            if (line.Contains($"Id Card No :{check}") || line.Contains($"Phone No :{check}"))
            {
                dirList.Add(line);
            }
        }
    }

    return dirList;
}

Notice the .Split() function. 注意.Split()函数。 This will need to be adjusted depending on how your data is separated. 这需要根据数据的分离方式进行调整。

Also note how you will need to differentiate between "Id Card No :" and "Phone No :" to have some kind of intelligence in your search in case the text you search for happens to be in a different field. 另请注意,如果您搜索的文本恰好位于不同的字段中,您将需要区分“Id Card No:”和“Phone No:”以在搜索中获得某种智能。

If this list is large I would strongly recommend putting this data in a database and using a SQL query to search the items appropriately as databases are optimized to search for data items. 如果此列表很大,我强烈建议将此数据放入数据库并使用SQL查询来适当地搜索项目,因为数据库已经过优化以搜索数据项。

String searches are generally slow processing, and the sr.ReadToEnd() will put ALL the data in memory. 字符串搜索通常处理速度很慢,而sr.ReadToEnd()会将所有数据放入内存中。 If the file is huge, the memory that your application will consume can be quite large. 如果文件很大,那么应用程序将占用的内存可能非常大。

You can try using Linq in order to query the file. 您可以尝试使用Linq查询文件。 Often, file reading is a time consuming operation, that's why let's do it just once. 通常,文件读取是一项耗时的操作,这就是为什么我们只做一次。 In case you want to represent record in some custom format (ie Console.WriteLine(record); is not enough), you have to parse it, eg with a help of regular expressions . 如果您想以某种自定义格式表示record (即Console.WriteLine(record);还不够),您必须解析它,例如在正则表达式的帮助下。

Code: 码:

    using System.Linq; 
    using System.Text.RegularExpressions;
    ... 
    string path = @"C:\Users\Precision\Desktop\testing\data.txt";

    Console.WriteLine("Enter CNIC or Phone No");
    string check = Console.ReadLine();

    var records = File
      .ReadLines(path)
      .Where(line => line.Contains(check));

    Regex regex = new Regex(@"(?<name>[^:]+):\s*(?<value>\S*)");

    bool isFirstRecord = true; 

    foreach (string record in records) {
      if (isFirstRecord)
        Console.WriteLine("Data Found Against {0}", check);

      isFirstRecord = false;

      Dictionary<string, string> data = regex
        .Matches(record)
        .Cast<Match>()
        .ToDictionary(match => match.Groups["name"].Value.Trim(),
                      match => match.Groups["value"].Value.Trim(),
                      StringComparer.OrdinalIgnoreCase);

      Console.WriteLine(string.Join(Environment.NewLine, data
        .Select(pair => $"{pair.Key,-11} = {pair.Value}")));  
    }

    // If we haven't read any record 
    if (isFirstRecord) 
      Console.WriteLine("No Data Found");

Outcome: 结果:

Data Found Against 12345
Id Card No  = 123456789
Phone No    = 545454
First Name  = asasa
Surname     = asasa
House       = sas
Street      = as
Sector      = as
City        = asasas
Country     = asasa

If you want some specific output format, you can easily query data dictionary, eg 如果您想要一些特定的输出格式,您可以轻松查询data字典,例如

Console.WriteLine($"Id: {data["Id Card No"]}; Phone: {data["Phone No"]}");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM