在 Visual C++ 中执行基本文件 I/O

本文介绍如何在 Microsoft Visual C++ 或 Visual C++ .NET 中执行基本的文件输入/输出 (I/O) 操作。

原始产品版本: Visual C++
原始 KB 编号: 307398

摘要

如果你不熟悉.NET Framework,你会发现.NET Framework中用于文件操作的对象模型类似于FileSystemObject许多 Visual Studio 开发人员常用的 。

本文介绍了以下.NET Framework类库命名空间:

  • System::ComponentModel
  • System::Windows::Forms
  • System::Drawing

仍可以在.NET Framework中使用 FileSystemObjectFileSystemObject由于 是 COM) 组件的组件对象模型 (,因此.NET Framework要求通过互操作层访问对象。 如果要使用,.NET Framework会为你生成组件包装器。 但是,File.NET Framework中的 类、FileInfo类、DirectoryDirectoryInfo类和其他相关类提供的功能在 不使用互操作层开销的情况下提供FileSystemObject

演示的文件 I/O 操作

本文中的示例介绍了基本的文件 I/O 操作。 分 步示例 部分介绍如何创建演示以下六个文件 I/O 操作的示例程序:

读取文本文件

下面的示例代码使用 StreamReader 类来读取文本文件。 文件的内容将添加到 ListBox 控件。 块 try...catch 用于在文件为空时向程序发出警报。 有多种方法可以确定何时到达文件末尾;此示例使用 Peek 方法在阅读前检查下一行。

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);
}

在 Visual C++ 中,必须添加公共语言运行时支持编译器选项 (/clr:oldSyntax) ,才能成功将以前的代码示例编译为托管 C++。 若要添加公共语言运行时支持编译器选项,请执行以下步骤:

  1. 单击“ 项目”,然后单击“ <ProjectName> 属性”。

    注意

    <ProjectName> 是项目名称的占位符。

  2. 展开 “配置属性”,然后单击“ 常规”。

  3. 在右窗格中,单击以在 公共语言运行时支持项目设置中选择“公共语言运行时支持”、“旧语法 (/clr:oldSyntax) ”。

  4. 在“拨号计划(电话上下文)”框中,单击“浏览”以查找用户的拨号计划。

编写文本文件

此示例代码使用 StreamWriter 类创建和写入文件。 如果有现有文件,则可以以相同方式打开它。

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);

查看文件信息

此示例代码使用 FileInfo 类访问文件的属性。 此示例使用 Notepad.exe。 属性显示在 ListBox 控件中。

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()));

列出磁盘驱动器

此示例代码使用 DirectoryDrive 类列出系统上的逻辑驱动器。 对于此示例,结果显示在 ListBox 控件中。

listBox1->Items->Clear();
String* drives[] = Directory::GetLogicalDrives();
int numDrives = drives->get_Length();
for (int i=0; i<numDrives; i++)
{
    listBox1->Items->Add(drives[i]);
}

列出子文件夹

此示例代码使用 GetDirectories 类的 Directory 方法来获取文件夹列表。

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]);
}

列出文件

此示例代码使用 GetFiles 类的 Directory 方法获取文件列表。

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]);
}

当用户获得对文件的访问权限时,许多事情都可能会出错。 这些文件可能不存在,文件可能正在使用,或者用户可能没有权限访问他们尝试访问的文件夹的文件。 编写代码来处理可能生成的异常时,请考虑这些可能性。

分步示例

  1. 启动 Visual Studio .NET。

  2. 在"文件"菜单上,指向"新建",然后单击"项目"。

  3. 在“ 项目类型”下,单击“ Visual C++ 项目”。 在“模板”部分下,单击“Windows 窗体应用程序” (.NET)

  4. 在“名称”框中键入KB307398C:\在“位置”框中键入,然后单击“确定”。

  5. 在“设计”视图中打开 Form1 窗体,然后按 F4 打开 “属性” 窗口。

  6. “属性” 窗口中,展开 “大小” 文件夹。 在“ 宽度 ”框中,键入 700。 在“ 高度 ”框中,键入 320

  7. Form1 添加一个 ListBox 控件和六个按钮控件。

    注意

    若要查看工具箱,请单击“视图”菜单上的“工具箱”。

  8. “属性” 窗口中,更改这些控件的 LocationNameSizeTabIndexText 属性,如下所示:

    控件 ID 位置 名称 Size TabIndex Text
    button1 500, 32 button1 112, 23 1 读取文本文件
    button2 500, 64 button2 112, 23 2 写入文本文件
    button3 500, 96 button3 112, 23 3 查看文件信息
    button4 500, 128 button4 112, 23 4 列出驱动器
    button5 500, 160 button5 112, 23 5 列出子文件夹
    button6 500, 192 button6 112, 23 6 列出文件
    listBox1 24, 24 listBox1 450, 200 0 listBox1
  9. 打开 Form1.h 文件。 在 Form1 类声明中,使用以下代码声明一个私有 String 变量:

    private:
    String *windir;
    
  10. Form1 类构造函数中,添加以下代码:

    windir = System::Environment::GetEnvironmentVariable("windir");
    
  11. 若要执行文件输入输出操作,请 System::IO 添加 命名空间。

  12. 按 SHIFT+F7 在“设计”视图中打开 Form1 。 双击“ 读取文本文件 ”按钮,然后粘贴以下代码:

    // 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);
    }
    
  13. 在“Form1 设计”视图中,双击“ 写入文本文件” 按钮,然后粘贴以下代码:

    // 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);
    
  14. 在“Form1 设计”视图中,双击“ 查看文件信息 ”按钮,然后将以下代码粘贴到 方法中:

    // 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()));
    
  15. 在“Form1 设计”视图中,双击“列出驱动器”按钮,然后粘贴以下代码:

    // 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]);
    }
    
  16. 在“Form1 设计”视图中,双击“列出子文件夹”按钮,然后粘贴以下代码:

    // 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]);
    }
    
  17. 在“Form1 设计”视图中,双击“列出文件”按钮,然后粘贴以下代码:

    // 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]);
    }
    
  18. 若要生成并运行程序,请按 Ctrl+F5。

完整代码示例

//Form1.h
#pragma once

namespace KB307398
{
    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 KB307398;

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;
}

References

有关详细信息,请访问 Microsoft 支持部门。 有关如何在 C++ 的托管扩展中创建 Windows 窗体的详细信息,请参阅 ManagedCWinFormWiz Visual Studio .NET 帮助中的示例。