Click here to Skip to main content
11,481,404 members (64,498 online)
Click here to Skip to main content

Basic stuff on Files, Directories and Streams

, 26 Jun 2002 147.4K 871 28
Rate this:
Please Sign up or sign in to vote.
Demonstrates the use of the reader/writer classes as well as the file/directory info classes

Introduction

Most common applications require reading and writing of files. There are numerous classes in the .NET BCL that provide various methods for creating and manipulating files and directories. In this article I'll cover the basic operations that you might have to perform with files. Since the functionality offered by most of the classes discussed here is too extensive to be completely covered, I only demonstrate some really common  uses of these classes. The readers can then explore the rest of the functionality on their own. The first version of this article used C# examples, but in this refined and expanded version I have used Managed C++. The article comprises of various techniques and is not in the form of a top-to-down tutorial. I welcome requests for more tips or techniques that readers would like to see included in the article.

Getting file information

For this we can use the System.IO.FileInfo class which has several instance methods for performing various file operations. As a short example we'll retrieve some information on Windows Notepad. I've used a native API call to retrieve the Windows directory as I couldn't figure out the .NET way of doing it. I'd be obliged if someone could tell me how to do it using .NET. Show is a user defined function that I use for a padded output.

void FileInfoDemo()
{
    TCHAR WinPath[MAX_PATH+1];
    GetWindowsDirectory(WinPath,MAX_PATH+1);
    String* NotepadPath = WinPath;
    NotepadPath = String::Concat(NotepadPath,S"\\notepad.exe");

    FileInfo* finfo = new FileInfo(NotepadPath);
    Show("Name",finfo->Name);
    Show("Directory",finfo->Directory);
    Show("Extension",finfo->Extension);
    Show("Length",__box(finfo->Length));
    Show("FullName",finfo->FullName);
    Show("CreationTime ",finfo->CreationTime.ToString()); 
}

Basically, all we do is to specify the path to the file in the constructor. Now we can use some very useful Properties to query information regarding our file. The FileInfo class has methods that return various stream readers and writers, but there are better methods to read and write to files as I'll be covering, later in this article.

Enumerate sub-directories and files

We use the DirectoryInfo class to enumerate sub-directories and files in a particular folder. It has two methods among many others called GetFiles and GetDirectories, the former returning a FileInfo array and the latter returning a DirectoryInfo array.

void DirectoryInfoDemo1()
{
    DirectoryInfo* dinfo = new DirectoryInfo("C:\\");
    DirectoryInfo* subdirs[] = dinfo->GetDirectories();
    Console::WriteLine("Sub-Directories for C:\\");
    Console::WriteLine("-----------------------");
    for(int i=0; i<subdirs->Length; i++)
        Show((i+1).ToString(),subdirs->Item[i]);
}

void DirectoryInfoDemo2()
{
    DirectoryInfo* dinfo = new DirectoryInfo("C:\\");
    FileInfo* filesindir[] = dinfo->GetFiles();
    Console::WriteLine("Files under C:\\");
    Console::WriteLine("---------------");
    for(int i=0; i<filesindir->Length; i++)
        Show((i+1).ToString(),filesindir->Item[i]); 
}

Binary files

We can read and write binary files using the BinaryReader and BinaryWriter classes. Just for fun, let's create a simple 16 bit COM format executable. We can write it using just 4 lines of 16 bit assembler as shown below. It simply calls Interrupt 21h Function 02h which outputs the character held in DL. I have also given the machine code equivalents of these assembler statements. So all we do is create an array holding these 8 bytes and then we use the BinaryWriter class to write to a file. Now we can actually run this file and it will print an 'A' on screen.

MOV AH,02h    ; B4 02
MOV DL,41h    ; B2 41
INT 21h       ; CD 21
INT 20h       ; CD 20
void BinaryWriterDemo()
{
    Console::WriteLine("Creating C:\\nish.com");
    Console::WriteLine("This will output an 'A' to the console");
    FileStream* fs = new FileStream("C:\\nish.com",
    FileMode::Create,FileAccess::Write);
    BinaryWriter* bw = new BinaryWriter(fs);
    unsigned char SomeBinaryData __gc[] = 
        {0xb4,0x02,0xb2,0x41,0xcd,0x21,0xcd,0x20};
    bw->Write(SomeBinaryData);
    bw->Flush();
    bw->Close();
}

Now I'll show you how to use the BinaryReader class to read the binary file we created above and display the bytes in the file.

void BinaryReaderDemo()
{
    Console::WriteLine("Reading C:\\nish.com");
    FileStream* fs = new FileStream("C:\\nish.com",
    FileMode::Open,FileAccess::Read);
    BinaryReader* br = new BinaryReader(fs);
    unsigned char c;
    while(br->PeekChar() != -1)
    {
        c = br->ReadByte();
        Console::Write("{0:X2} ",__box(c));
    }
    br->Close();
    Console::WriteLine();
}

One small issue with the BinaryReader.ReadByte Method is that it throws an EndOfStreamException instead of indicating it using a special return value. To avoid handling the exception and doing it the old-C style way, which may or may not be a good thing, I have used PeekChar which will return the next byte but will not move the file pointer.

Text Files

There are more than one way of reading and writing text files, but here I'll show you how to use the StreamWriter and StreamReader classes. They remind me very much of the MFC CStdioFile class. The StreamReader class has a ReadLine method and the StreamWrite class has a WriteLine method both of which are exactly similar in behaviour with the CStdioFile::ReadString and CStdioFile::WriteString methods. Both the classes have constructors that take a file path as argument and thus we don't need to create the FileStream object first as we had to do with the BinaryReader and BinaryWriter classes.

void StreamWriterDemo()
{
    Console::WriteLine("Creating C:\\TempFile.txt");
    StreamWriter *sw = new StreamWriter ("C:\\TempFile.txt");
    sw->WriteLine("This is the first line"); 
    sw->WriteLine("This is the second line"); 
    sw->WriteLine("This is the third/last line"); 
    sw->Close();
}

void StreamReaderDemo()
{
    Console::WriteLine("Reading C:\\TempFile.txt");
    Console::WriteLine("-----------------------");
    StreamReader* sr = new StreamReader ("C:\\TempFile.txt");
    String* s;
    while(s = sr->ReadLine())
        Console::WriteLine(s);
    sr->Close();
}

Reading from a string

They think of everything, don't they. StringReader is a class derived from TextReader that allows us to read from a string directly. There is also a corresponding StringWriter class. I am not very definite about it's purpose, but I guess someone would find some use for it. Maybe it might prove useful for parsing simple strings.

void StringReaderDemo(String* s)
{
    Console::WriteLine("Reading the string [{0}]",s);
    StringReader* sr = new StringReader(s);
    int c;
    while((c = sr->Read()) != -1)
        Console::Write("{0} ",__box(Convert::ToChar(c)));
    Console::WriteLine(); 
    sr->Close();
} 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Nish Nishant

United States United States
Nish Nishant is a Software Architect/Consultant based out of Columbus, Ohio. He has over 15 years of software industry experience in various roles including Lead Software Architect, Principal Software Engineer, and Product Manager. Nish is a recipient of the annual Microsoft Visual C++ MVP Award since 2002 (13 consecutive awards as of 2014).

Nish is an industry acknowledged expert in the Microsoft technology stack. He authored
C++/CLI in Action for Manning Publications in 2005, and had previously co-authored
Extending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition, he has over 140 published technology articles on CodeProject.com and another 250+ blog articles on his
WordPress blog. Nish is vastly experienced in team management, mentoring teams, and directing all stages of software development.

Contact Nish : You can reach Nish on his google email id voidnish.

Website and Blog

Comments and Discussions

 
QuestionC++? Pin
WolfSupernova16-Jun-03 9:06
memberWolfSupernova16-Jun-03 9:06 
GeneralWindows Directory Pin
Michael G Hawksworth12-Aug-02 6:45
sussMichael G Hawksworth12-Aug-02 6:45 
GeneralRe: Windows Directory Pin
Nishant S14-Aug-02 19:15
editorNishant S14-Aug-02 19:15 
GeneralUpdated - June 27 [with some difficulty] Pin
Nishant S27-Jun-02 7:34
memberNishant S27-Jun-02 7:34 
GeneralNice basics! Pin
Martin 'Lucanus cervus'15-May-02 2:16
memberMartin 'Lucanus cervus'15-May-02 2:16 
GeneralRe: Nice basics! Pin
Nish [BusterBoy]15-May-02 2:26
memberNish [BusterBoy]15-May-02 2:26 
Generalusefull code Pin
Alexandr Khilov1-Apr-02 13:28
memberAlexandr Khilov1-Apr-02 13:28 
GeneralRe: usefull code Pin
Alexandr Khilov1-Apr-02 13:30
memberAlexandr Khilov1-Apr-02 13:30 
GeneralRe: usefull code Pin
Nish [BusterBoy]1-Apr-02 17:25
memberNish [BusterBoy]1-Apr-02 17:25 
GeneralRe: usefull code Pin
Nish [BusterBoy]1-Apr-02 17:24
memberNish [BusterBoy]1-Apr-02 17:24 
GeneralFileStream fs = new FileStream("nish.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite Pin
Anonymous5-Mar-02 7:16
memberAnonymous5-Mar-02 7:16 
Needs to be:

FileStream fs = new FileStream(@"D:\c#.net\misc\writefiletest\nish.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);

GeneralConsole.Write("{0}",Convert.ToChar(b1)); Pin
Katsarakis26-Oct-01 11:29
memberKatsarakis26-Oct-01 11:29 
GeneralRe: Console.Write("{0}",Convert.ToChar(b1)); Pin
Nish [BusterBoy]26-Oct-01 18:03
memberNish [BusterBoy]26-Oct-01 18:03 
GeneralFileInfo f = new FileInfo ("nish.txt"); Pin
Katsarakis26-Oct-01 11:05
memberKatsarakis26-Oct-01 11:05 
GeneralRe: FileInfo f = new FileInfo ("nish.txt"); Pin
Nish [BusterBoy]26-Oct-01 18:07
memberNish [BusterBoy]26-Oct-01 18:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 27 Jun 2002
Article Copyright 2001 by Nish Nishant
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid