Click here to Skip to main content
Click here to Skip to main content

Basic stuff on Files, Directories and Streams

, 26 Jun 2002
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 Sivakumar

United States United States
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
 
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.
 
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.
 
Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
 
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.

Comments and Discussions

 
GeneralFileStream fs = new FileStream("nish.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite PinmemberAnonymous5-Mar-02 7:16 
GeneralConsole.Write("{0}",Convert.ToChar(b1)); PinmemberKatsarakis26-Oct-01 11:29 
GeneralRe: Console.Write("{0}",Convert.ToChar(b1)); PinmemberNish [BusterBoy]26-Oct-01 18:03 
GeneralFileInfo f = new FileInfo ("nish.txt"); PinmemberKatsarakis26-Oct-01 11:05 
GeneralRe: FileInfo f = new FileInfo ("nish.txt"); PinmemberNish [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
Web04 | 2.8.1411022.1 | Last Updated 27 Jun 2002
Article Copyright 2001 by Nish Sivakumar
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid