locked
Reading Data from Text File

    Question

  • Hi, 

    I am trying to read data from a text file with C# in Visual Studio. I've got a file laid out like so: 

    Network_Type:
    	CDMA
    	GSM
    	Other
    
    Computer_Type:
    	Desktop
    	Notebook/Laptop
    	Server
    	Disk Array/Raid
    	Single Disk
    	Other

    I want to read each item as a group. For example, the Computer_Type items need to be read and inserted into a combobox and the same goes for Network_Type. 

    I've tried using the Microsoft documentation, but there are way too many classes and options and I have not yet found one that works entirely with Windows 8.1. Here's the working code I have (that retrieves the entire file if I print it in debug):

    //get to the assets folder
                StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
                folder = await folder.GetFolderAsync("Assets");
                
                //find the file
                var configFile = await folder.GetFileAsync("config.txt");
                
                //read from the file
                var stream = await configFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
                var size = stream.Size;
    
                using (var inputStream = stream.GetInputStreamAt(0))
                {
                    DataReader dataReader = new DataReader(inputStream);               
                }

    What does this code need to look like to read that way? I can figure out how to insert the values into the combobox myself, I'm just struggling with how to actually read the file. 

    Thanks a lot for your help. It is greatly appreciated.

    Thursday, July 10, 2014 4:02 PM

Answers

  • Cool, there is nothing right or wrong. It is just that you start doing things and with time you get perfection. Here you can ask for advise if you are not sure. By the way I was just trying and I have your file parser :)

    public async Task<Dictionary<string, List<string>>> ReadData(string fileName = "config.txt", string folderName = "Assets")
    {
        string groupPattern = @"^(.)+\:";
    
        string dataPattern = @"\t(.)+$";
    
        Dictionary<string, List<string>> data = new Dictionary<string, List<string>>();
    
        StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
    
        if (!String.IsNullOrWhiteSpace(folderName))
        {
            folder = await folder.GetFolderAsync(folderName);
        }
    
        StorageFile file = await folder.GetFileAsync(fileName);
    
        IList<string> lines = await FileIO.ReadLinesAsync(file);
    
        string latestGroup = null;
    
        if (lines != null)
        {
            foreach (string line in lines)
            {
                if (Regex.IsMatch(line, groupPattern))
                {
                    latestGroup = line.Replace(":", "").Trim();
    
                    data.Add(latestGroup, new List<string>());
                }
                else if (Regex.IsMatch(line, dataPattern) && latestGroup != null)
                {
                    data[latestGroup].Add(line.Trim());
                }
            }
        }
    
        return data;
    }

    But still I will say do it XML way.


    -- Vishal Kaushik --

    Please 'Mark as Answer' if my post answers your question and 'Vote as Helpful' if it helps you. Happy Coding!!!

    • Proposed as answer by Vishal Kaushik Thursday, July 10, 2014 5:36 PM
    • Marked as answer by JB-CI-IRS Thursday, July 10, 2014 6:34 PM
    Thursday, July 10, 2014 5:33 PM

All replies

  • Your file structure calls for a good parsing logic; there needs to be a good reason to have data in the format that you have in that file. Can you tell why are you not using XML or JSON format to put store this data? If there is really a genuine need I will try to help you with some algorithm.

    -- Vishal Kaushik --

    Please 'Mark as Answer' if my post answers your question and 'Vote as Helpful' if it helps you. Happy Coding!!!

    • Proposed as answer by Vishal Kaushik Thursday, July 10, 2014 5:36 PM
    Thursday, July 10, 2014 4:52 PM
  • I could definitely change the format of the file to something different. I'm not familiar with JSON so I would prefer to use XML.

    I've created an XML file that looks like this: 

    <ConfigFile>
      <NetworkType>
        <title>Network_Type</title>
    	<item>CDMA</item>
    	<item>GSM</item>
    	<item>Other</item>
      </NetworkType>
    
      <ComputerType>
        <title>Computer_Type</title>
    	<item>Desktop</item>
    	<item>Notebook/Laptop</item>
    	<item>Server</item>
    	<item>Disk Array/Raid</item>
    	<item>Single Disk</item>
    	<item>Other</item>
      </ComputerType>
    </ConfigFile>

    I haven't looked into reading from an XML file, so I'll do that now. Any pointers you have would be perfect. 

    Thanks again for your help.

    • Edited by JB-CI-IRS Thursday, July 10, 2014 5:12 PM added more details
    Thursday, July 10, 2014 4:57 PM
  • Cool, there is nothing right or wrong. It is just that you start doing things and with time you get perfection. Here you can ask for advise if you are not sure. By the way I was just trying and I have your file parser :)

    public async Task<Dictionary<string, List<string>>> ReadData(string fileName = "config.txt", string folderName = "Assets")
    {
        string groupPattern = @"^(.)+\:";
    
        string dataPattern = @"\t(.)+$";
    
        Dictionary<string, List<string>> data = new Dictionary<string, List<string>>();
    
        StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
    
        if (!String.IsNullOrWhiteSpace(folderName))
        {
            folder = await folder.GetFolderAsync(folderName);
        }
    
        StorageFile file = await folder.GetFileAsync(fileName);
    
        IList<string> lines = await FileIO.ReadLinesAsync(file);
    
        string latestGroup = null;
    
        if (lines != null)
        {
            foreach (string line in lines)
            {
                if (Regex.IsMatch(line, groupPattern))
                {
                    latestGroup = line.Replace(":", "").Trim();
    
                    data.Add(latestGroup, new List<string>());
                }
                else if (Regex.IsMatch(line, dataPattern) && latestGroup != null)
                {
                    data[latestGroup].Add(line.Trim());
                }
            }
        }
    
        return data;
    }

    But still I will say do it XML way.


    -- Vishal Kaushik --

    Please 'Mark as Answer' if my post answers your question and 'Vote as Helpful' if it helps you. Happy Coding!!!

    • Proposed as answer by Vishal Kaushik Thursday, July 10, 2014 5:36 PM
    • Marked as answer by JB-CI-IRS Thursday, July 10, 2014 6:34 PM
    Thursday, July 10, 2014 5:33 PM
  • Wow. Thank you so much. 

    I am trying to read the data from the XML file, but I am having a problem. Here is my code: 

    StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
                folder = await folder.GetFolderAsync("Assets");
                String path = folder.ToString()+"config.txt";
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(path);
                XmlNodeList itemList = doc.SelectNodes("ConfigFile/ImagingCIS/title");
                foreach (XmlNode title in itemList)
                {
                    //do something
                }
    

    For some reason, I get an error with XmlNode missing a directive. I have the line using System.Xml; at the top of my file, so I'm not sure why I'm getting this. 

    Is there a different way I should read in the values? 

    Thanks!

    Thursday, July 10, 2014 6:44 PM
  • There is another option, which works effectively and that is to use the DataContractSerializer, to serialize/de-serialize a List<MyStorageType> and read/persist this to a file(s). The advantage is you have a strongly typed list you can use LINQ to query.
    Thursday, July 10, 2014 7:55 PM