SUMMARY
This step-by-step article describes how to do six basic
file input/output (I/O) operations in Microsoft Visual C++ 2005 or in Microsoft Visual C++ .NET. If you are new to the .NET Framework,
you will find that the object model for file operations in the .NET Framework is similar to
the
FileSystemObject (FSO) that is popular with many Microsoft Visual Studio 6.0 developers. To
make the transition easier, the functionality that is demonstrated in this
article is based on the following Microsoft Knowledge Base article:
186118 How To Use FileSystemObject with
Visual Basic
You can still use the
FileSystemObject in the .NET Framework. Because the
FileSystemObject is a Component Object Model (COM) component, the .NET Framework requires that
access to the object be through the Interop layer. The .NET Framework generates a wrapper for
the component for you if you want to use it. However, the
File class, the
FileInfo class, the
Directory,
DirectoryInfo classes, and other related classes in the .NET Framework, offer
functionality that is not available with the FSO, without the overhead of the
Interop layer.
Requirements
The following list outlines the recommended hardware, software,
network infrastructure, and service packs that are required:
- Visual C++ 2005 or Visual C++ .NET
Demonstrated File I/O Operations
The examples in this article describe basic file I/O operations.
The "Step-by-Step Example" section describes how to create a sample program
that demonstrates the following six file I/O operations:
- Read a Text File
- Write a Text File
- View File Information
- List Disk Drives
- List Folders
- List Files
Read a Text File
The following sample code uses a
StreamReader class to read the System.ini file. The contents of the file are
added to a
ListBox control. The
try...catch block is used to alert the program if the file is empty. There
are many ways to determine when the end of the file is reached; this sample
uses the
Peek method to examine the next line before reading it.
listBox1->Items->Clear();
try
{
String* textFile = String::Concat(windir, (S"\\mytest.txt"));
StreamReader *reader=new StreamReader(textFile);
do
{
listBox1->Items->Add(reader->ReadLine());
}
while(reader->Peek() != -1);
}
catch (System::Exception *e)
{
listBox1->Items->Add(e);
}
}
Note In
Visual C++ 2005, you must add the common language runtime support compiler option (
/clr:oldSyntax) to successfully compile the previous code sample.
To add the common language runtime support compiler option, follow these steps:
- Click Project, and then click
ProjectName Properties.
Note ProjectName is a placeholder for the
name of the project. - Expand Configuration Properties, and then click
General.
- In the right pane, click to select Common Language Runtime Support, Old Syntax
(/clr:oldSyntax) in the
Common Language Runtime support project settings.
- Click
Apply, and then
click OK.
For more information about common language runtime support compiler options, visit the following Microsoft
Developer Network (MSDN) Web site:
Write a Text File
This sample code uses a
StreamWriter class to create and write to a file. If you have an existing
file, you can open it in the same way.
StreamWriter* pwriter = new StreamWriter(S"c:\\KBTest.txt");
pwriter->WriteLine(S"File created using StreamWriter class.");
pwriter->Close();
listBox1->Items->Clear();
String *filew = new String(S"File Written to C:\\KBTest.txt");
listBox1->Items->Add(filew);
View File Information
This sample code uses a
FileInfo class to access a file's properties. Notepad.exe is used in this
sample. The properties appear in a
ListBox control.
listBox1->Items->Clear();
String* testfile = String::Concat(windir, (S"\\notepad.exe"));
FileInfo *pFileProps =new FileInfo(testfile);
listBox1->Items->Add(String::Concat(S"File Name = ", (pFileProps->get_FullName() )) );
listBox1->Items->Add(String::Concat(S"Creation Time = ", (pFileProps->get_CreationTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Last Access Time = " ,(pFileProps->get_LastAccessTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Last Write Time = ", (pFileProps->get_LastWriteTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Size = ", (pFileProps->get_Length() ).ToString()) );
List Disk Drives
This sample code uses the
Directory and
Drive classes to list the logical drives on a system. For this sample,
the results appear in a
ListBox control.
listBox1->Items->Clear();
String* drives[] = Directory::GetLogicalDrives();
int numDrives = drives->get_Length();
for (int i=0; i<numDrives; i++)
{
listBox1->Items->Add(drives[i]);
}
List Subfolders
This sample code uses the
GetDirectories method of the
Directory class to obtain a list of folders.
listBox1->Items->Clear();
String* dirs[] = Directory::GetDirectories(windir);
int numDirs = dirs->get_Length();
for (int i=0; i<numDirs; i++)
{
listBox1->Items->Add(dirs[i]);
}
List Files
This sample code uses the
GetFiles method of the
Directory class to obtain a listing of files.
listBox1->Items->Clear();
String* files[]= Directory::GetFiles(this->windir);
int numFiles = files->get_Length();
for (int i=0; i<numFiles; i++)
{
listBox1->Items->Add(files[i]);
}
Many things can go wrong when a user gains access to files. The files
may not exist, the files may be in use, or users may not have rights on the
files of folders that they are trying to access. Consider
these possibilities when you write code to handle the exceptions that may
be generated.
Step-by-Step Example
- Start Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET 2003.
- On the File menu, point to
New, and then click Project.
- Under Project Types, click
Visual C++ Projects. Under Templates section, click
Windows Forms Application (.NET).
Note In Visual Studio 2005, click
Visual C++ under Project Types. Under Templates, click
Windows Forms Application. - Type Q307398 in the
Name box, type C:\ in the
Location box, and then click
OK.
- Open the Form1 form in the Design
view, and then press F4 to open the
Propertries window.
- In the Properties window, expand the Size
folder. In the Width box, type 700.
In the Height box, type
320.
- Add one ListBox control and six
Button controls to Form1.
Note To view the toolbox, click Toolbox on the View menu. - In the Properties window, change the
Location, the Name, the Size, the
TabIndex, and the Text properties of these
controls as follows:
|
button1 | 500, 32 | button1 | 112,
23 | 1 | Read Text File |
button2 | 500, 64 | button2 | 112,
23 | 2 | Write Text File |
button3 | 500, 96 | button3 | 112,
23 | 3 | View File Information |
button4 | 500, 128 | button4 | 112,
23 | 4 | List Drives |
button5 | 500, 160 | button5 | 112,
23 | 5 | List Subfolders |
button6 | 500, 192 | button6 | 112,
23 | 6 | List Files |
listBox1 | 24, 24 | listBox1 | 450,
200 | 0 | listBox1 |
- Open the Form1.h file. In the Form1 class declaration,
declare one private String variable with the following code:
private:
String *windir;
- In the Form1 class constructor add the following code:
windir = System::Environment::GetEnvironmentVariable("windir");
- To perform file Input output operations,add the System.IO
namespace.
- Press SHIFT+F7 to open Form1 in
Design view. Double-click Read Text File, and then paste the following code:
// How to read a text file:
// Use try...catch to deal with a 0 byte file or a non-existant file.
listBox1->Items->Clear();
try
{
String* textFile = String::Concat(windir, (S"\\mytest.txt"));
StreamReader *reader=new StreamReader(textFile);
do
{
listBox1->Items->Add(reader->ReadLine());
}
while(reader->Peek() != -1);
}
catch(FileNotFoundException *ex)
{
listBox1->Items->Add(ex);
}
catch (System::Exception *e)
{
listBox1->Items->Add(e);
}
- In the Form1 Design view, double-click Write Text File, and then paste the following code:
// This demonstrates how to create and to write to a text file.
StreamWriter* pwriter = new StreamWriter(S"c:\\KBTest.txt");
pwriter->WriteLine(S"The file was created by using the StreamWriter class.");
pwriter->Close();
listBox1->Items->Clear();
String *filew = new String(S"File written to C:\\KBTest.txt");
listBox1->Items->Add(filew);
- In the Form1 Design view, double-click Write Text File, double-click View File Information, and then paste the following code in the method:
// This code retrieves file properties. The example uses Notepad.exe.
listBox1->Items->Clear();
String* testfile = String::Concat(windir, (S"\\notepad.exe"));
FileInfo *pFileProps =new FileInfo(testfile);
listBox1->Items->Add(String::Concat(S"File Name = ", (pFileProps->get_FullName() )) );
listBox1->Items->Add(String::Concat(S"Creation Time = ", (pFileProps->get_CreationTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Last Access Time = " ,(pFileProps->get_LastAccessTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Last Write Time = ", (pFileProps->get_LastWriteTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Size = ", (pFileProps->get_Length() ).ToString()) );
- In the Form1 Design view, double-click View File Information, and then paste the following code:
// This demonstrates how to obtain a list of disk drives.
listBox1->Items->Clear();
String* drives[] = Directory::GetLogicalDrives();
int numDrives = drives->get_Length();
for (int i=0; i<numDrives; i++)
{
listBox1->Items->Add(drives[i]);
}
- In the Form1 Design view, double-click the List Subfolders button, and then paste the following code:
// This code obtains a list of folders. This example uses the Windows folder.
listBox1->Items->Clear();
String* dirs[] = Directory::GetDirectories(windir);
int numDirs = dirs->get_Length();
for (int i=0; i<numDirs; i++)
{
listBox1->Items->Add(dirs[i]);
}
- In the Form1 Design view, double-click List Files, and then paste the following code:
// This code obtains a list of files. This example uses the Windows folder.
listBox1->Items->Clear();
String* files[]= Directory::GetFiles(this->windir);
int numFiles = files->get_Length();
for (int i=0; i<numFiles; i++)
{
listBox1->Items->Add(files[i]);
}
- To build and then run the program, press CTRL+F5.
Complete Code Sample
//Form1.h
#pragma once
namespace Q307398
{
using namespace System;
using namespace System::IO;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public __gc class Form1 : public System::Windows::Forms::Form
{
private:
String *windir;
public:
Form1(void)
{
windir = System::Environment::GetEnvironmentVariable("windir");
InitializeComponent();
}
protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private: System::Windows::Forms::Button * button1;
private: System::Windows::Forms::Button * button2;
private: System::Windows::Forms::Button * button3;
private: System::Windows::Forms::Button * button4;
private: System::Windows::Forms::Button * button5;
private: System::Windows::Forms::Button * button6;
private: System::Windows::Forms::ListBox * listBox1;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container * components;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->button1 = new System::Windows::Forms::Button();
this->button2 = new System::Windows::Forms::Button();
this->button3 = new System::Windows::Forms::Button();
this->button4 = new System::Windows::Forms::Button();
this->button5 = new System::Windows::Forms::Button();
this->button6 = new System::Windows::Forms::Button();
this->listBox1 = new System::Windows::Forms::ListBox();
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(500, 32);
this->button1->Name = S"button1";
this->button1->Size = System::Drawing::Size(112, 23);
this->button1->TabIndex = 1;
this->button1->Text = S"Read Text File";
this->button1->Click += new System::EventHandler(this, button1_Click);
//
// button2
//
this->button2->Location = System::Drawing::Point(500, 64);
this->button2->Name = S"button2";
this->button2->Size = System::Drawing::Size(112, 23);
this->button2->TabIndex = 2;
this->button2->Text = S"Write Text File";
this->button2->Click += new System::EventHandler(this, button2_Click);
//
// button3
//
this->button3->Location = System::Drawing::Point(500, 96);
this->button3->Name = S"button3";
this->button3->Size = System::Drawing::Size(112, 23);
this->button3->TabIndex = 3;
this->button3->Text = S"View File Information";
this->button3->Click += new System::EventHandler(this, button3_Click);
//
// button4
//
this->button4->Location = System::Drawing::Point(500, 128);
this->button4->Name = S"button4";
this->button4->Size = System::Drawing::Size(112, 23);
this->button4->TabIndex = 4;
this->button4->Text = S"List Drives";
this->button4->Click += new System::EventHandler(this, button4_Click);
//
// button5
//
this->button5->Location = System::Drawing::Point(500, 160);
this->button5->Name = S"button5";
this->button5->Size = System::Drawing::Size(112, 23);
this->button5->TabIndex = 5;
this->button5->Text = S"List Subfolders";
this->button5->Click += new System::EventHandler(this, button5_Click);
//
// button6
//
this->button6->Location = System::Drawing::Point(500, 188);
this->button6->Name = S"button6";
this->button6->Size = System::Drawing::Size(112, 23);
this->button6->TabIndex = 6;
this->button6->Text = S"List Files";
this->button6->Click += new System::EventHandler(this, button6_Click);
//
// listBox1
//
this->listBox1->Location = System::Drawing::Point(24, 24);
this->listBox1->Name = S"listBox1";
this->listBox1->Size = System::Drawing::Size(450, 199);
this->listBox1->TabIndex = 0;
//
// Form1
//
this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
this->ClientSize = System::Drawing::Size(692, 293);
this->Controls->Add(this->listBox1);
this->Controls->Add(this->button6);
this->Controls->Add(this->button5);
this->Controls->Add(this->button4);
this->Controls->Add(this->button3);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
this->Name = S"Form1";
this->Text = S"Form1";
this->ResumeLayout(false);
}
private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)
{// This code shows how to read a text file.
// The try...catch code is to deal with a 0 byte file or a non-existant file.
listBox1->Items->Clear();
try
{
String* textFile = String::Concat(windir, (S"\\mytest.txt"));
StreamReader *reader=new StreamReader(textFile);
do
{
listBox1->Items->Add(reader->ReadLine());
}
while(reader->Peek() != -1);
}
catch(FileNotFoundException *ex)
{
listBox1->Items->Add(ex);
}
catch (System::Exception *e)
{
listBox1->Items->Add(e);
}
}
private: System::Void button2_Click(System::Object * sender, System::EventArgs * e)
{// This code demonstrates how to create and to write to a text file.
StreamWriter* pwriter = new StreamWriter(S"c:\\KBTest.txt");
pwriter->WriteLine(S"The file was created by using the StreamWriter class.");
pwriter->Close();
listBox1->Items->Clear();
String *filew = new String(S"The file was written to C:\\KBTest.txt");
listBox1->Items->Add(filew);
}
private: System::Void button3_Click(System::Object * sender, System::EventArgs * e)
{// This code retrieves file properties. This example uses Notepad.exe.
listBox1->Items->Clear();
String* testfile = String::Concat(windir, (S"\\notepad.exe"));
FileInfo *pFileProps =new FileInfo(testfile);
listBox1->Items->Add(String::Concat(S"File Name = ", (pFileProps->get_FullName() )) );
listBox1->Items->Add(String::Concat(S"Creation Time = ", (pFileProps->get_CreationTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Last Access Time = " ,(pFileProps->get_LastAccessTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Last Write Time = ", (pFileProps->get_LastWriteTime() ).ToString()) );
listBox1->Items->Add(String::Concat(S"Size = ", (pFileProps->get_Length() ).ToString()) );
}
private: System::Void button4_Click(System::Object * sender, System::EventArgs * e)
{// The code demonstrates how to obtain a list of disk drives.
listBox1->Items->Clear();
String* drives[] = Directory::GetLogicalDrives();
int numDrives = drives->get_Length();
for (int i=0; i<numDrives; i++)
{
listBox1->Items->Add(drives[i]);
}
}
private: System::Void button5_Click(System::Object * sender, System::EventArgs * e)
{// This code obtains a list of folders. This example uses the Windows folder.
listBox1->Items->Clear();
String* dirs[] = Directory::GetDirectories(windir);
int numDirs = dirs->get_Length();
for (int i=0; i<numDirs; i++)
{
listBox1->Items->Add(dirs[i]);
}
}
private: System::Void button6_Click(System::Object * sender, System::EventArgs * e)
{// This code obtains a list of files. This example uses the Windows folder.
listBox1->Items->Clear();
String* files[]= Directory::GetFiles(this->windir);
int numFiles = files->get_Length();
for (int i=0; i<numFiles; i++)
{
listBox1->Items->Add(files[i]);
}
}
};
}
//Form1.cpp
#include "stdafx.h"
#include "Form1.h"
#include <windows.h>
using namespace My;
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
Application::Run(new Form1());
return 0;
}