在 Visual C++ 中执行基本文件 I/O
本文介绍如何在 Microsoft Visual C++ 或 Visual C++ .NET 中执行基本的文件输入/输出(I/O)操作。
原始产品版本: Visual C++
原始 KB 数: 307398
总结
如果你不熟悉 .NET Framework,你会发现 .NET Framework 中文件操作的对象模型类似于 FileSystemObject
许多 Visual Studio 开发人员所欢迎的对象模型。
若要简化转换,请参阅 如何将 FileSystemObject 与 Visual Basic 配合使用。
有关本文的 Visual C# .NET 版本,请参阅 如何在 Visual C# 中执行基本文件 I/O。
本文介绍以下 .NET Framework 类库命名空间:
System::ComponentModel
System::Windows::Forms
System::Drawing
你仍然可以在 .NET Framework 中使用 FileSystemObject
。 FileSystemObject
由于它是组件对象模型 (COM) 组件,因此 .NET Framework 要求访问该对象是通过互操作层访问的。 如果要使用它,.NET Framework 将为组件生成包装器。 但是,File
类、FileInfo
类、 DirectoryInfo
Directory
类以及 .NET Framework 中的其他相关类提供的功能,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++。 若要添加公共语言运行时支持编译器选项,请执行以下步骤:
单击“项目”,然后单击“<ProjectName> 属性”。
注意
<ProjectName> 是项目名称的占位符。
展开 配置属性,然后单击“ 常规”。
在右窗格中,单击以在公共语言运行时支持项目设置中选择 公共语言运行时支持、旧语法(/clr:oldSyntax )。
单击“应用”,然后单击“确定”。
编写文本文件
此示例代码使用类 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()));
列出磁盘驱动器
此示例代码使用 Directory
类 Drive
列出系统上的逻辑驱动器。 对于此示例,结果将显示在 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]);
}
当用户获得对文件的访问权限时,可能会出错。 这些文件可能不存在,文件可能正在使用中,或者用户可能无权访问他们尝试访问的文件夹的文件。 编写代码来处理可能生成的异常时,请考虑这些可能性。
分步示例
启动 Visual Studio .NET。
在 “文件” 菜单上,指向 “新建” ,然后单击 “项目” 。
在“项目类型”下,单击“视觉对象C++项目。 在“模板”部分,单击Windows 窗体应用程序(.NET)。
在“名称”框中键入KB307398,在
C:\
“位置”框中键入,然后单击“确定”。在 “设计”视图中打开 Form1 窗体,然后按 F4 打开 “属性” 窗口。
在 “属性” 窗口中,展开“ 大小 ”文件夹。 在 “宽度 ”框中,键入 700。 在 “高度 ”框中,键入 320。
向 Form1 添加一个 ListBox 控件和六个按钮控件。
注意
若要查看工具箱,请单击“视图”菜单上的“工具箱”。
在“属性”窗口中,按如下所示更改“位置”、“名称”、“大小”、“TabIndex”和“文本”属性:
控制 ID 位置 名称 大小 TabIndex 文本 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 打开 Form1.h 文件。 在
Form1
类声明中,使用以下代码声明一个私有String
变量:private: String *windir;
在
Form1
类构造函数中,添加以下代码:windir = System::Environment::GetEnvironmentVariable("windir");
若要执行文件输入输出操作,请添加
System::IO
命名空间。按 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); }
在 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);
在 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()));
在 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]); }
在 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]); }
在 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]); }
若要生成并运行程序,请按 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;
}
参考
有关详细信息,请访问Microsoft 支持部门。 有关如何在C++的托管扩展中创建 Windows 窗体的详细信息,请参阅 ManagedCWinFormWiz
Visual Studio .NET 帮助中的示例。