Saturday, May 30, 2009

CRC32 File Verification Hashing

using System;
using System.Collections;
using System.IO;
using System.Security.Cryptography;

namespace CodeProject
{
///
///
///

public class CRC32 : HashAlgorithm
{
protected static uint AllOnes = 0xffffffff;
protected static Hashtable cachedCRC32Tables;
protected static bool autoCache;

protected uint[] crc32Table;
private uint m_crc;

///
/// Returns the default polynomial (used in WinZip, Ethernet, etc)
///

public static uint DefaultPolynomial
{
get { return 0x04C11DB7; }
}

///
/// Gets or sets the auto-cache setting of this class.
///

public static bool AutoCache
{
get { return autoCache; }
set { autoCache = value; }
}

///
/// Initialize the cache
///

static CRC32()
{
cachedCRC32Tables = Hashtable.Synchronized( new Hashtable() );
autoCache = true;
}

public static void ClearCache()
{
cachedCRC32Tables.Clear();
}


///
/// Builds a crc32 table given a polynomial
///

///
///
protected static uint[] BuildCRC32Table( uint ulPolynomial )
{
uint dwCrc;
uint[] table = new uint[256];

// 256 values representing ASCII character codes.
for (int i = 0; i < 256; i++)
{
dwCrc = (uint)i;
for (int j = 8; j > 0; j--)
{
if((dwCrc & 1) == 1)
dwCrc = (dwCrc >> 1) ^ ulPolynomial;
else
dwCrc >>= 1;
}
table[i] = dwCrc;
}

return table;
}


///
/// Creates a CRC32 object using the DefaultPolynomial
///

public CRC32() : this(DefaultPolynomial)
{
}

///
/// Creates a CRC32 object using the specified Creates a CRC32 object
///

public CRC32(uint aPolynomial) : this(aPolynomial, CRC32.AutoCache)
{
}

///
/// Construct the
///

public CRC32(uint aPolynomial, bool cacheTable)
{
this.HashSizeValue = 32;

crc32Table = (uint []) cachedCRC32Tables[aPolynomial];
if ( crc32Table == null )
{
crc32Table = CRC32.BuildCRC32Table(aPolynomial);
if ( cacheTable )
cachedCRC32Tables.Add( aPolynomial, crc32Table );
}
Initialize();
}

///
/// Initializes an implementation of HashAlgorithm.
///

public override void Initialize()
{
m_crc = AllOnes;
}

///
///
///

///
///
///
protected override void HashCore(byte[] buffer, int offset, int count)
{
// Save the text in the buffer.
for (int i = offset; i < count; i++)
{
ulong tabPtr = (m_crc & 0xFF) ^ buffer[i];
m_crc >>= 8;
m_crc ^= crc32Table[tabPtr];
}
}

///
///
///

///
protected override byte[] HashFinal()
{
byte [] finalHash = new byte [ 4 ];
ulong finalCRC = m_crc ^ AllOnes;

finalHash[0] = (byte) ((finalCRC >> 24) & 0xFF);
finalHash[1] = (byte) ((finalCRC >> 16) & 0xFF);
finalHash[2] = (byte) ((finalCRC >> 8) & 0xFF);
finalHash[3] = (byte) ((finalCRC >> 0) & 0xFF);

return finalHash;
}

///
/// Computes the hash value for the specified Stream.
///

new public byte[] ComputeHash(Stream inputStream)
{
byte [] buffer = new byte [4096];
int bytesRead;
while ( (bytesRead = inputStream.Read(buffer, 0, 4096)) > 0 )
{
HashCore(buffer, 0, bytesRead);
}
return HashFinal();
}


///
/// Overloaded. Computes the hash value for the input data.
///

new public byte[] ComputeHash(byte[] buffer)
{
return ComputeHash(buffer, 0, buffer.Length);
}

///
/// Overloaded. Computes the hash value for the input data.
///

///
///
///
///
new public byte[] ComputeHash( byte[] buffer, int offset, int count )
{
HashCore(buffer, offset, count);
return HashFinal();
}
}

}

Open a Zip File and Reading it

// ZipFile.cs
//
// Copyright (C) 2001 Mike Krueger
// Copyright (C) 2004 John Reilly
//
// This file was translated from java, it was part of the GNU Classpath
// Copyright (C) 2001 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library. Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.
//
// As a special exception, the copyright holders of this library give you
// permission to link this library with independent modules to produce an
// executable, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting executable under
// terms of your choice, provided that you also meet, for each linked
// independent module, the terms and conditions of the license of that
// module. An independent module is a module which is not derived from
// or based on this library. If you modify this library, you may extend
// this exception to your version of the library, but you are not
// obligated to do so. If you do not wish to do so, delete this
// exception statement from your version.

using System;
using System.Collections;
using System.IO;
using System.Text;

using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.Zip.Compression;

namespace ICSharpCode.SharpZipLib.Zip
{

///
/// This class represents a Zip archive. You can ask for the contained
/// entries, or get an input stream for a file entry. The entry is
/// automatically decompressed.
///
/// This class is thread safe: You can open input streams for arbitrary
/// entries in different threads.
///

///
Author of the original java version : Jochen Hoenicke
///

///
///
/// using System;
/// using System.Text;
/// using System.Collections;
/// using System.IO;
///
/// using ICSharpCode.SharpZipLib.Zip;
///
/// class MainClass
/// {
/// static public void Main(string[] args)
/// {
/// ZipFile zFile = new ZipFile(args[0]);
/// Console.WriteLine("Listing of : " + zFile.Name);
/// Console.WriteLine("");
/// Console.WriteLine("Raw Size Size Date Time Name");
/// Console.WriteLine("-------- -------- -------- ------ ---------");
/// foreach (ZipEntry e in zFile) {
/// DateTime d = e.DateTime;
/// Console.WriteLine("{0, -10}{1, -10}{2} {3} {4}", e.Size, e.CompressedSize,
/// d.ToString("dd-MM-yy"), d.ToString("t"),
/// e.Name);
/// }
/// }
/// }
///

///

public class ZipFile : IEnumerable
{
string name;
string comment;
Stream baseStream;
ZipEntry[] entries;

///
/// Opens a Zip file with the given name for reading.
///

///
/// An i/o error occurs
///

///
/// The file doesn't contain a valid zip archive.
///

public ZipFile(string name) : this(File.OpenRead(name))
{
}

///
/// Opens a Zip file reading the given FileStream
///

///
/// An i/o error occurs.
///

///
/// The file doesn't contain a valid zip archive.
///

public ZipFile(FileStream file)
{
this.baseStream = file;
this.name = file.Name;
ReadEntries();
}

///
/// Opens a Zip file reading the given Stream
///

///
/// An i/o error occurs
///

///
/// The file doesn't contain a valid zip archive.

/// The stream provided cannot seek
///

public ZipFile(Stream baseStream)
{
this.baseStream = baseStream;
this.name = null;
ReadEntries();
}


///
/// Read an unsigned short in little endian byte order.
///

///
/// An i/o error occurs.
///

///
/// The file ends prematurely
///

int ReadLeShort()
{
return baseStream.ReadByte() | baseStream.ReadByte() << 8;
}

///
/// Read an int in little endian byte order.
///

///
/// An i/o error occurs.
///

///
/// The file ends prematurely
///

int ReadLeInt()
{
return ReadLeShort() | ReadLeShort() << 16;
}

///
/// Search for and read the central directory of a zip file filling the entries
/// array. This is called exactly once by the constructors.
///

///
/// An i/o error occurs.
///

///
/// The central directory is malformed or cannot be found
///

void ReadEntries()
{
// Search for the End Of Central Directory. When a zip comment is
// present the directory may start earlier.
//
// TODO: The search is limited to 64K which is the maximum size of a trailing comment field to aid speed.
// This should be compatible with both SFX and ZIP files but has only been tested for Zip files
// Need to confirm this is valid in all cases.
// Could also speed this up by reading memory in larger blocks?


if (baseStream.CanSeek == false) {
throw new ZipException("ZipFile stream must be seekable");
}

long pos = baseStream.Length - ZipConstants.ENDHDR;
if (pos <= 0) {
throw new ZipException("File is too small to be a Zip file");
}

long giveUpMarker = Math.Max(pos - 0x10000, 0);

do {
if (pos < giveUpMarker) {
throw new ZipException("central directory not found, probably not a zip file");
}
baseStream.Seek(pos--, SeekOrigin.Begin);
} while (ReadLeInt() != ZipConstants.ENDSIG);

int thisDiskNumber = ReadLeShort();
int startCentralDirDisk = ReadLeShort();
int entriesForThisDisk = ReadLeShort();
int entriesForWholeCentralDir = ReadLeShort();
int centralDirSize = ReadLeInt();
int offsetOfCentralDir = ReadLeInt();
int commentSize = ReadLeShort();

byte[] zipComment = new byte[commentSize];
baseStream.Read(zipComment, 0, zipComment.Length);
comment = ZipConstants.ConvertToString(zipComment);

/* Its seems possible that this is too strict, more digging required.
if (thisDiskNumber != 0 || startCentralDirDisk != 0 || entriesForThisDisk != entriesForWholeCentralDir) {
throw new ZipException("Spanned archives are not currently handled");
}
*/

entries = new ZipEntry[entriesForWholeCentralDir];
baseStream.Seek(offsetOfCentralDir, SeekOrigin.Begin);

for (int i = 0; i < entriesForWholeCentralDir; i++) {
if (ReadLeInt() != ZipConstants.CENSIG) {
throw new ZipException("Wrong Central Directory signature");
}

int versionMadeBy = ReadLeShort();
int versionToExtract = ReadLeShort();
int bitFlags = ReadLeShort();
int method = ReadLeShort();
int dostime = ReadLeInt();
int crc = ReadLeInt();
int csize = ReadLeInt();
int size = ReadLeInt();
int nameLen = ReadLeShort();
int extraLen = ReadLeShort();
int commentLen = ReadLeShort();

int diskStartNo = ReadLeShort(); // Not currently used
int internalAttributes = ReadLeShort(); // Not currently used

int externalAttributes = ReadLeInt();
int offset = ReadLeInt();

byte[] buffer = new byte[Math.Max(nameLen, commentLen)];

baseStream.Read(buffer, 0, nameLen);
string name = ZipConstants.ConvertToString(buffer, nameLen);

ZipEntry entry = new ZipEntry(name, versionToExtract, versionMadeBy);
entry.CompressionMethod = (CompressionMethod)method;
entry.Crc = crc & 0xffffffffL;
entry.Size = size & 0xffffffffL;
entry.CompressedSize = csize & 0xffffffffL;
entry.DosTime = (uint)dostime;

if (extraLen > 0) {
byte[] extra = new byte[extraLen];
baseStream.Read(extra, 0, extraLen);
entry.ExtraData = extra;
}

if (commentLen > 0) {
baseStream.Read(buffer, 0, commentLen);
entry.Comment = ZipConstants.ConvertToString(buffer, commentLen);
}

entry.ZipFileIndex = i;
entry.Offset = offset;
entry.ExternalFileAttributes = externalAttributes;

entries[i] = entry;
}
}

///
/// Closes the ZipFile. This also closes all input streams managed by
/// this class. Once closed, no further instance methods should be
/// called.
///

///
/// An i/o error occurs.
///

public void Close()
{
entries = null;
lock(baseStream) {
baseStream.Close();
}
}

///
/// Returns an enumerator for the Zip entries in this Zip file.
///

///
/// The Zip file has been closed.
///

public IEnumerator GetEnumerator()
{
if (entries == null) {
throw new InvalidOperationException("ZipFile has closed");
}

return new ZipEntryEnumeration(entries);
}

///
/// Return the index of the entry with a matching name
///

/// Entry name to find
/// If true the comparison is case insensitive
/// The index position of the matching entry or -1 if not found
///
/// The Zip file has been closed.
///

public int FindEntry(string name, bool ignoreCase)
{
if (entries == null) {
throw new InvalidOperationException("ZipFile has been closed");
}

for (int i = 0; i < entries.Length; i++) {
if (string.Compare(name, entries[i].Name, ignoreCase) == 0) {
return i;
}
}
return -1;
}

///
/// Indexer property for ZipEntries
///

[System.Runtime.CompilerServices.IndexerNameAttribute("EntryByIndex")]
public ZipEntry this[int index] {
get {
return (ZipEntry) entries[index].Clone();
}
}

///
/// Searches for a zip entry in this archive with the given name.
/// String comparisons are case insensitive
///

///
/// The name to find. May contain directory components separated by slashes ('/').
///
///
/// The zip entry, or null if no entry with that name exists.
///

///
/// The Zip file has been closed.
///

public ZipEntry GetEntry(string name)
{
if (entries == null) {
throw new InvalidOperationException("ZipFile has been closed");
}

int index = FindEntry(name, true);
return index >= 0 ? (ZipEntry) entries[index].Clone() : null;
}

///
/// Checks, if the local header of the entry at index i matches the
/// central directory, and returns the offset to the data.
///

///
/// The start offset of the (compressed) data.
///

///
/// The stream ends prematurely
///

///
/// The local header signature is invalid, the entry and central header file name lengths are different
/// or the local and entry compression methods dont match
///

long CheckLocalHeader(ZipEntry entry)
{
lock(baseStream) {
baseStream.Seek(entry.Offset, SeekOrigin.Begin);
if (ReadLeInt() != ZipConstants.LOCSIG) {
throw new ZipException("Wrong Local header signature");
}

short shortValue = (short)ReadLeShort(); // version required to extract
if (shortValue > ZipConstants.VERSION_MADE_BY) {
throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", shortValue));
}

shortValue = (short)ReadLeShort(); // general purpose bit flags.
if ((shortValue & 0x30) != 0) {
throw new ZipException("The library doesnt support the zip version required to extract this entry");
}

if (entry.CompressionMethod != (CompressionMethod)ReadLeShort()) {
throw new ZipException("Compression method mismatch");
}

// Skip time, crc, size and csize
long oldPos = baseStream.Position;
baseStream.Position += ZipConstants.LOCNAM - ZipConstants.LOCTIM;

if (baseStream.Position - oldPos != ZipConstants.LOCNAM - ZipConstants.LOCTIM) {
throw new EndOfStreamException();
}

// TODO make test more correct... cant compare lengths as was done originally as this can fail for MBCS strings
int storedNameLength = ReadLeShort();
if (entry.Name.Length > storedNameLength) {
throw new ZipException("file name length mismatch");
}

int extraLen = storedNameLength + ReadLeShort();
return entry.Offset + ZipConstants.LOCHDR + extraLen;
}
}

///
/// Creates an input stream reading the given zip entry as
/// uncompressed data. Normally zip entry should be an entry
/// returned by GetEntry().
///

///
/// the input stream.
///

///
/// The ZipFile has already been closed
///

///
/// The compression method for the entry is unknown
///

///
/// The entry is not found in the ZipFile
///

public Stream GetInputStream(ZipEntry entry)
{
if (entries == null) {
throw new InvalidOperationException("ZipFile has closed");
}

int index = entry.ZipFileIndex;
if (index <>= entries.Length || entries[index].Name != entry.Name) {
index = FindEntry(entry.Name, true);
if (index < 0) {
throw new IndexOutOfRangeException();
}
}
return GetInputStream(index);
}


///
/// Creates an input stream reading the zip entry based on the index passed
///

///
/// An input stream.
///

///
/// The ZipFile has already been closed
///

///
/// The compression method for the entry is unknown
///

///
/// The entry is not found in the ZipFile
///

public Stream GetInputStream(int entryIndex)
{
if (entries == null) {
throw new InvalidOperationException("ZipFile has closed");
}

long start = CheckLocalHeader(entries[entryIndex]);
CompressionMethod method = entries[entryIndex].CompressionMethod;
Stream istr = new PartialInputStream(baseStream, start, entries[entryIndex].CompressedSize);

switch (method) {
case CompressionMethod.Stored:
return istr;
case CompressionMethod.Deflated:
return new InflaterInputStream(istr, new Inflater(true));
default:
throw new ZipException("Unknown compression method " + method);
}
}

///
/// Gets the comment for the zip file.
///

public string ZipFileComment {
get {
return comment;
}
}

///
/// Gets the name of this zip file.
///

public string Name {
get {
return name;
}
}

///
/// Gets the number of entries in this zip file.
///

///
/// The Zip file has been closed.
///

public int Size {
get {
if (entries != null) {
return entries.Length;
} else {
throw new InvalidOperationException("ZipFile is closed");
}
}
}

class ZipEntryEnumeration : IEnumerator
{
ZipEntry[] array;
int ptr = -1;

public ZipEntryEnumeration(ZipEntry[] arr)
{
array = arr;
}

public object Current {
get {
return array[ptr];
}
}

public void Reset()
{
ptr = -1;
}

public bool MoveNext()
{
return (++ptr < array.Length);
}
}

class PartialInputStream : InflaterInputStream
{
Stream baseStream;
long filepos, end;

public PartialInputStream(Stream baseStream, long start, long len) : base(baseStream)
{
this.baseStream = baseStream;
filepos = start;
end = start + len;
}

public override int Available
{
get {
long amount = end - filepos;
if (amount > Int32.MaxValue) {
return Int32.MaxValue;
}

return (int) amount;
}
}

public override int ReadByte()
{
if (filepos == end) {
return -1; //ok
}

lock(baseStream) {
baseStream.Seek(filepos++, SeekOrigin.Begin);
return baseStream.ReadByte();
}
}

public override int Read(byte[] b, int off, int len)
{
if (len > end - filepos) {
len = (int) (end - filepos);
if (len == 0) {
return 0;
}
}
lock(baseStream) {
baseStream.Seek(filepos, SeekOrigin.Begin);
int count = baseStream.Read(b, off, len);
if (count > 0) {
filepos += len;
}
return count;
}
}

public long SkipBytes(long amount)
{
if (amount < 0) {
throw new ArgumentOutOfRangeException();
}
if (amount > end - filepos) {
amount = end - filepos;
}
filepos += amount;
return amount;
}
}
}
}

Size of Folder in Bytes (Deep or Shallow)

using System;
using System.IO;

public class Folder {
private static double sizeInBytes;

public static double Size(string directory, bool deep) {
DirectoryInfo dir = new DirectoryInfo(directory);
foreach(FileInfo f in dir.GetFiles()) {
sizeInBytes += f.Length;
}
if(deep) {
foreach(DirectoryInfo d in dir.GetDirectories()) {
Size(d.FullName, deep);
}
}
return sizeInBytes;
}

static void Main() {
Console.WriteLine("The total folder size in bytes is {0}", Folder.Size(@"c:\sonysys", true));
}
}

Ini File class

using System;
using System.Collections.Generic;
using System.Text;

//This namespace is for easy INI reading ad writing, designed to be practically errorless, you dont need to worry about things like if .exists .add .set etc, just .set
//XML is similar to INI, but not as simple and easily modified by humans
//INI is ideal for server settings etc.

//any keys found NOT under a group header will be put in group MAIN

//WARNING: THIS INI FILE DOES NOT SUPPORT COMMENTS
//FORMAT IS AS FOLLOWS:
//[GROUP]
//item1=True
//item2=some text here
//[GROUP2]
//soemthing=3
using System.IO;
namespace EasyINI
{
//A class to handle all file IO for multiple savable settings
//This class will create on-demand, an INI file of settings, keys need not be added before being assigned
public class INIFile
{
//this class handles the saving and loading of the file
protected string fname;
protected List inigroupnames;
protected List inigroups;

public INIFile(string @filename)
{
fname = filename;
inigroups = new List();
inigroupnames = new List();
reloadFile();
}

public INIGroup Group(string name)
{
name = name.ToUpper();
int i = inigroupnames.IndexOf(name);
if (i == -1)
{
return null;
}
else
{
return inigroups[i];
}
}

public void setValue(string group, string key, string value)
{
addGroup(group); //create the group (if not already existing)
Group(group).setValue(key, value); //set the value
}

public string getValue(string group, string key)
{
group = group.ToUpper();
key = key.ToLower();
if (inigroupnames.IndexOf(group) == -1)
{
return string.Empty;
}
else
{
return Group(group).getValue(key);
}
}

public void addGroup(string group)
{
group = group.ToUpper();
if (inigroupnames.IndexOf(group) == -1)
{
inigroupnames.Add(group);
inigroups.Add(new INIGroup(this));
}
}

public bool saveFile() //bool returned indicates the success of the save process
{
try
{
FileStream strm = new FileStream(fname, FileMode.Create, FileAccess.Write);
StreamWriter W = new StreamWriter(strm);
if(inigroupnames.Count > 0)
{
for (int i = 0; i < inigroupnames.Count; i++)
{
INIGroup grp = inigroups[i];
if (grp.getCount() > 0) //only save this group if it has content
{
W.WriteLine("[" + inigroupnames[i] + "]");
for (int k = 0; k < grp.getCount(); k++)
W.WriteLine(grp.getKey(k) + @"=" + grp.getValue(k));
W.WriteLine(" ");
}
}
}
W.Close();
strm.Close();
return true;
}
catch
{
return false;
}
}

public void reloadFile()
{
inigroups.Clear();
inigroupnames.Clear();

if (File.Exists(fname))
{
string strline;
string currentGroup = "MAIN";
FileStream strm = new FileStream(fname, FileMode.Open, FileAccess.Read);
StreamReader R = new StreamReader(strm);
while (R.EndOfStream != true)
{
strline = R.ReadLine(); //get line
if (strline.StartsWith("["))
{
//this is a group header
currentGroup = strline.Substring(1, strline.Length - 2);
}
else
{
//this is a key=value entry
string[] keyval = strline.Split('=');
if (keyval.Length == 2)
setValue(currentGroup, keyval[0], keyval[1]);
}
}
R.Close();
strm.Close();
}
}
}

//This sub-class is used by the INIFile class, it handles the keys and values within an INI group
public class INIGroup
{
//this class handles the settings of values
protected INIFile owner;
public List inikeys;
public List inivalues;
public INIGroup(INIFile parent)
{
owner = parent;
inikeys = new List();
inivalues = new List();
}

public void setValue(string key, string value)
{
key = key.ToLower();
int i = inikeys.IndexOf(key);
if (i == -1)
{
inikeys.Add(key);
inivalues.Add(value);
}
else
{
inivalues[i] = value;
}
owner.saveFile();
}

public string getValue(string key)
{
key = key.ToLower();
int i = inikeys.IndexOf(key);
if (i == -1)
{
return string.Empty;
}
else
{
return inivalues[i];
}
}

public string getKey(int index)
{
if (index > -1 && index < getCount())
{
return inikeys[index];
}
else
{
//out of range
throw new IndexOutOfRangeException("Index was out of range, must be non-negative and less than total key count");
}
}

public string getValue(int index)
{
if (index > -1 && index < getCount())
{
return inivalues[index];
}
else
{
//out of range
throw new IndexOutOfRangeException("Index was out of range, must be non-negative and less than total key count");
}
}

public int getCount()
{
return inikeys.Count;
}

}
}

Browse For Folder in .NET 1.0

//Have To Reference System.Design.dll

/*
Usage:
-
BrowseForFolder browse = new BrowseForFolder();
string savePath = browse.Show();
*/

using System;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace iCode_Library.NET
{

public class BrowseForFolder: FolderNameEditor
{

FolderNameEditor.FolderBrowser dirBrowser;
public BrowseForFolder()
{
dirBrowser = new FolderNameEditor.FolderBrowser();
}
public string Show()
{
//set the Description label
dirBrowser.Description = "Select Folder";
dirBrowser.ShowDialog(); //show the Windows
return dirBrowser.DirectoryPath + @"\"; // return whatever path choosen
}

}
}

File Content To Array

private ArrayList fileContentToArrayList(string filePath)
{

System.Collections.ArrayList arrListLines = new System.Collections.ArrayList();
//read the file content one by one
try
{
StreamReader fl = new StreamReader(filePath, System.Text.Encoding.ASCII);
//StreamReader fl = File.OpenText(filePath,);
string line = "";
while((line = fl.ReadLine()) != null )
{
arrListLines.Add(line);
}


}
catch(Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message, "Failed reading file");
return null;
}
return arrListLines;
}

Reading a text file with StreamReader

// Reading a text file with StreamReader

private void ImportCountries()
{
string delimiter = ",";
string fileName = @"c:\countrylist3.csv";

StreamReader sr = new StreamReader(fileName);

try
{
while (sr.Peek() >= 0)
{
string r = sr.ReadLine();
string[] items = r.Split(delimiter.ToCharArray());
}
}
finally
{
sr.Close();
}
}