Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
237 views
in Technique[技术] by (71.8m points)

search - Searching a text file c#

I am making an application which saves and loads information about products. These products have a product name, customer name and a firmware location. I have got them to save and load correctly, however I am now trying to find a way where I can search for a product on its name. Here is my products class:

    //private product data
    private string productName;

    public string getProductName()
    {
        return this.productName;
    }

    public void setProductName (string inProductName)
    {
        this.productName = inProductName;
    }

    private string customerName;

    public string getCustomerName()
    {
        return this.customerName;
    }

    public void setCustomerName (string inCustomerName)
    {
        this.customerName = inCustomerName;
    }

    private string firmwareLocation;

    public string getFirmwareLocation()
    {
        return this.firmwareLocation;
    }

    public void setFirmwareLocation (string inFirmwareLocation)
    {
        this.firmwareLocation = inFirmwareLocation;
    }


    //constructor 
    public Product (string inProductName, string inCustomerName, string inFirmwareLocation)
    {
        productName = inProductName;
        customerName = inCustomerName;
        firmwareLocation = inFirmwareLocation;
    }


    //save method
    public void Save (System.IO.TextWriter textOut)
    {
        textOut.WriteLine(productName);
        textOut.WriteLine(customerName);
        textOut.WriteLine(firmwareLocation);
    }

    public bool Save(string filename)
    {
        System.IO.TextWriter textOut = null;
        try
        {
            textOut = new System.IO.StreamWriter(filename, true);
            Save(textOut);
        }
        catch
        {
            return false;
        }
        finally
        {
            if (textOut != null)
            {
                textOut.Close();
            }
        }
        return true;
    }

    public static Product Load (System.IO.TextReader textIn)
    {
        Product result = null;

        try
        {
            string productName = textIn.ReadLine();
            string customerName = textIn.ReadLine();
            string firmwareLocation = textIn.ReadLine();
        }
        catch
        {
            return null;
        }
        return result;
    }


}

}

I was wondering how I would search through the file say search a product name, and it would find it and display the product name, customer name and firmware location

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Firstly, some recommendations for your current class...

The Save function is exceptionally poor for pulling out data from the file again. Do this instead:

public class Product {
    // Note that I've added a constructor for this class - this'll help later
    public Product(string productName, string customerName, string firmwareLocation) {
        this.productName = productName;
        this.customerName = customerName;
        this.firmwareLocation = firmwareLocation;
    }

    public void Save (System.IO.TextWriter textOut)
    {
        textOut.WriteLine(String.Format(
            "{0},{1},{2}", this.productName, this.customerName, this.firmwareLocation);
    }
}

So instead of getting this:

...
Awesome Hairdryer
Nick Bull
C://hair.firmware
Awesome TV
Nick Bull
C://tv.firmware
...

you get this:

...
Awesome Hairdryer,Nick Bull,C://hair.firmware
Awesome TV,Nick Bull,C://tv.firmware
...

Once you've done that...

It's a really easy question. One liner, with some examples of methods used as filters for "searching", if you want them:

IEnumerable<string> lines = File.ReadLines(pathToTextFile)
    .TakeWhile(line => line.Contains("Nick Bull"));

EDIT: Even neater one-liner, returning a Product collection:

List<Product> lines = File.ReadLines(pathToTextFile)
    .TakeWhile(line => line.Contains("Nick Bull"))
    .Select(line => new Product(line.Split(',')[0], line.Split(',')[1], line.Split(',')[2])
    .ToList();

To iterate through them and do other more complicated stuff, you could read them all then do stuff:

var lines = File.ReadAllLines(filePath);
var products = new List<Product>();

foreach (string line in lines) {
    if (Regex.IsMatch(line, @"super awesome regex")) {
        string[] lineItems = line.Split(','); // Splits line at commas into array
        products.Add(new Product(line[0], line[1], line[2]); // Thanks to our constructor
    }
}

foreach (var product in products) {
    Console.WriteLine(String.Format("Product name: {0}", product.productName));
}

Search functionality update

To search, use these functions:

public enum ProductProperty {
    ProductName,
    CustomerName,
    FirmwareLocation
}

List<Product> GetAllProductsFromFile(string filePath) {
    if (!File.Exists(filePath)) throw FileNotFoundException("Couldn't find " + filePath);

    return File.ReadLines(filePath)
       .Select(line => new Product(line.Split(',')[0], line.Split(',')[1], line.Split(',')[2])
        .ToList();
}

function SearchProductsByProperty(IEnumerable<Product> products, ProductProperty productProperty, string value) {
    return products.ToList().Where(product => 
        (productProperty == ProductProperty.ProductName) ? product.productName == productName :
        (productProperty == ProductProperty.CustomerName) ? product.customerName == customerName :
        (productProperty == ProductProperty.FirmwareName) ? product.firmwareName == firmwareName : throw new NotImplementedException("ProductProperty must be ProductProperty.ProductName, ProductProperty.CustomerName or ProductProperty.FirmwareName");
    );
}

Then:

var products = GetAllProductsFromFile(filePath);
var searchedProducts = SearchProductsByProperty(products, ProductProperty.ProductName, "Awesome TV");

foreach (var product in searchedProducts) {
    // Each product will have a `ProductName` equal to "Awesome TV".
    // Finally, get the customer name by doing this within this foreach loop, using `product.customerName`
    Console.WriteLine(product.customerName);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...