user1861145
user1861145

Reputation:

Reading to hash table from file c#

(In this windows form application) I'm trying to read data from a file into a hash table and populate text boxes with the data in the hash table but when I run the code I'm always thrown the exception "Item has already been added. Key in dictionary: '' Key being added: '' "

Initial code:

string[] fileLines = File.ReadAllLines(@"C:path/ajand.txt");

foreach (string line in fileLines)
{
    // to split the first 9 chars in the string and use them as key values                
    string[] match = Regex.Split(line, line.Substring(0,9));
    hT.Add(match[0], line);
}

so i tried checking for key duplicates with the following code

 string[] fileLines = File.ReadAllLines(@"C:path/ajand.txt");

 foreach (string line in fileLines)
 {
     string[] match = Regex.Split(line, line.Substring(0,9));

     if(!hT.ContainsKey(match[0])) // to check duplicates
     hT.Add(match[0], line);            
 }

But when I run the program the corresponding text boxes are not populated with the data that "seems" to have been added to the hash table. Please any ideas what the problem is.

Upvotes: 2

Views: 6324

Answers (4)

DreTaX
DreTaX

Reputation: 836

    public static Hashtable HashtableFromFile(string path)
    {
        try
        {
            using (FileStream stream = new FileStream(path, FileMode.Open))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                return (Hashtable)formatter.Deserialize(stream);
            }
        }
        catch
        {
            return new Hashtable(); 
        }            
    }

Upvotes: 1

Daniel Gabriel
Daniel Gabriel

Reputation: 3985

See if this helps. It assumes that the separator between the date and the rest of the line is a space. It will try to parse the date into a DateTime object and use it as a key. It will use the rest of the line as the value. The fact that the indexer is used to put values into the dictionary eliminates duplicate key problems, but at the same time it will overwrite values if you have entries that have the same date. In this case only the last entry with that date will be saved into the dictionary.

var lines = File.ReadAllLines(@"C:\path\ajand.txt");

foreach (var line in lines) {
    var index = line.Trim().IndexOf(" ");
    if (index == -1) {
        continue;
    }

    DateTime key;
    if (DateTime.TryParseExact(line.Substring(0, index), out key)) {
        hT[key] = line.Substring(index);
    }
}

Upvotes: 0

Francis Gagnon
Francis Gagnon

Reputation: 3675

If I understand correctly you could use a function like this one:

public static Dictionary<string, string> LoadActivityLookup(string filePath) {
    const int KEY_LENGTH = 10;
    var newLookup = new Dictionary<string, string>();
    foreach (string line in File.ReadAllLines(filePath)) {
        if (line.Length < KEY_LENGTH) continue;
        string key = line.Substring(0, KEY_LENGTH);
        if (!newLookup.ContainsKey(key)) {
            string value = line.Substring(KEY_LENGTH);
            newLookup.Add(key, value);
        }
    }
    return newLookup;
}

Dictionaries are great for repeatedly looking up keys in a large set of keys. But if you only need to hold a bunch of key/value pairs in a collection so that you can later iterate through them, I would go with a List<> instead.

Here is a version of the above function which uses a StreamReader instead of loading the complete file in a string array.

public static Dictionary<string, string> LoadActivityLookup(string filePath) {
    const int KEY_LENGTH = 10;
    var newLookup = new Dictionary<string, string>();
    using (StreamReader rdr = new StreamReader(filePath)) {
        string line = rdr.ReadLine();
        while (line != null) {
            if (line.Length < KEY_LENGTH) {
                line = rdr.ReadLine();
                continue;
            } 
            string key = line.Substring(0, KEY_LENGTH);
            if (!newLookup.ContainsKey(key)) {
                string value = line.Substring(KEY_LENGTH);
                newLookup.Add(key, value);
            }
            line = rdr.ReadLine();
        }
    }
    return newLookup;
}

Upvotes: 1

Jaime Torres
Jaime Torres

Reputation: 10515

In order to remove duplicates, you can simply use the index to add/update to the hashtable:

string[] fileLines = File.ReadAllLines(@"C:path/ajand.txt");

foreach (string line in fileLines)
{
    // to split the first 10 chars in the string and use them as key values                
    string key = line.Length > 10 ? line.Substring(0,10) : line;
    hT[key] = line;
}

Upvotes: 0

Related Questions