Well I got it to work, but it turns out to be a terrible headache. Instead of arrays I used a List of Dictionary elements.
Allow me to share the solution with you. But first, to reiterate the problem.
The Problem
In the example code in my original post above, I first created an uninitialized array to hold FileStream objects:
Code:
FileStream[] QUERYFILEHOOK
The problem is, how can I initialize the array now? In my example I showed,
Code:
QUERYFILEHOOK[1] = new FileStream(@K:\data\fruit.txt", FileMode.Open);
But that's not how you initialize an array, is it? It should look something like,
Code:
QUERYFILEHOOK = new FileStream(@K:\data\fruit.txt", FileMode.Open)[3];
So now I've made an array of FileStream objects but each one is pointing to the same file. That's not what I want. Normally you would start with a blank array of proper size, and populate it later. Hence you may be tempted to write a line such as,
Code:
FileStream[] QUERYFILEHOOK = new FileStream()[3];
But this will generate an error:
Quote:
|
'System.IO.FileStream' does not contain a constructor that takes 0 arguments
|
A Solution
Well I got this code to work using List and Dictionary elements. First the code:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace learning_try_catch_filehandles {
public partial class Form1 : Form {
int max = 2; // Number of files we're going to be looking at;
Dictionary<FileStream, StreamReader> FILE = new Dictionary<FileStream, StreamReader>();
List<Dictionary<FileStream, StreamReader>> FILELIST = new List<Dictionary<FileStream, StreamReader>>(2);
FileStream tmp_stream;
StreamReader tmp_reader;
Dictionary<FileStream, StreamReader> tmp_dict;
public Form1() {
InitializeComponent();
// Initialize proper number of FILELIST elements (see comment 1 below)
for (int i = 0; i < max; ++i) {
FILELIST.Add(tmp_dict);
}
}
private void button1_Click(object sender, EventArgs e) {
try {
tmp_stream = new FileStream(@"K:\data\set1.txt", FileMode.Open);
tmp_reader = new StreamReader(tmp_stream);
tmp_dict = new Dictionary<FileStream, StreamReader>();
tmp_dict.Add(tmp_stream, tmp_reader);
FILELIST[0] = tmp_dict;
tmp_stream = new FileStream(@"K:\data\set2.txt", FileMode.Open);
tmp_reader = new StreamReader(tmp_stream);
tmp_dict.Add(tmp_stream, tmp_reader);
FILELIST[1] = tmp_dict;
} catch (IOException ex) {
MessageBox.Show("Uhoh...\r\n" + ex.ToString());
}
}
private void button2_Click(object sender, EventArgs e) {
string row;
// Now we go through the actual data
for (int i = 0; i < 2; i++) {
tmp_dict = FILELIST[i];
foreach (KeyValuePair<FileStream, StreamReader> kvp in FILELIST[i]) { // See comment 2
row = kvp.Value.ReadLine();
while (row != null) {
row = row.Trim();
if (row == "") continue; // Ignore blank lines
textbox.Text += row + "\r\n";
row = kvp.Value.ReadLine();
}
textbox.Text += "\r\n";
} // END foreach
} // END for
} // END button2_Click
}// END class Form1
}
If you notice in the code above there are to comment references (comment 1 and 2). Let me address them now:
Comment 1: I'm looping through and adding 'max' number of empty dictionary elements to FILELIST. The reason I'm doing this is because in my particular application I need to know for sure exactly which file is connected to which index within the List. Therefore I can't just add each Dictionary element ( using
FILELIST.Add() ) with my actual data.
So I first create an empty set so that I may add the actual Dictionary elements using the index notation,
FILELIST[0] = tmp_dict;.
Also, as an aside, although in my example code I'm adding the two Dictionary elements using explicit file names, it's hopefully obvious that I can do that in a loop instead (which I'll be doing in my actual project).
Comment 2: I'm using the
foreach loop in concert with the
KeyValuePair function to get the Key and Value (which is the FileStream and StreamReader objects respectively) for this particular Dictionary element.
Even though there is only a single Dictionary element in each List I personally don't know of a better way to access the Dictionary's Value without an explicit reference to the Key (which I'm trying to avoid to keep this generic), even though there is only a single Dictionary element in each List element.
Final Thoughts
First off, I'm not sure that I even need to keep the FileStream references once I have the StreamReader objects created. In such a case I could do this all with just a List with no Dictionary.
Secondly, you may be thinking that this is an excessive amount of code just to open a few files; to that I would reply,
- I am new to C#. There's no reason to think this is the most efficient way to code a solution.
- Remember that C# is written by Microsoft. I don't think anyone, in the history of the company, has accused them of being efficient at anything. ;)
As it turns out, after getting this to work. I feel like it's too complicated to keep. Since the code I'm writing will be maintained by someone else I don't feel comfortable handing this sort of convolution onto some poor soul. Hence I've decided that I will go ahead and just manually create each file handle with easy to understand variable names.
Not ideal, I know, but this mess is, well, too messy. :P