在 Visual C++ 中執行基本檔案 I/O
本文說明如何在 Visual C++ 或 Visual C++ .NET 中執行 visual Microsoft 的基本檔案輸入/輸出 (I/O) 作業。
原始產品版本: Visual C++
原始 KB 編號: 307398
摘要
如果您不熟悉 .NET Framework,您會發現 .NET Framework 中檔案作業的物件模型類似於 FileSystemObject
許多 Visual Studio 開發人員的熱門物件模型。
若要簡化轉換,請參閱 如何搭配 Visual Basic 使用 FileSystemObject。
如需本文的 Visual C# .NET 版本,請參閱 如何在 Visual C# 中執行基本檔案 I/O。
本文參考下列 .NET Framework 類別庫命名空間:
System::ComponentModel
System::Windows::Forms
System::Drawing
您仍然可以 FileSystemObject
在 .NET Framework 中使用 。 FileSystemObject
因為 是元件物件模型 (COM) 元件,因此 .NET Framework 需要透過 Interop 層存取物件。 如果您想要使用它,.NET Framework 會為您產生元件的包裝函式。 不過, File
類別、 FileInfo
類別、 Directory
類別 DirectoryInfo
,以及 .NET Framework 中的其他相關類別,提供無法使用 FileSystemObject
的功能,而不需要 Interop 層的額外負荷。
示範的檔案 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++ 中,您必須新增 Common Language Runtime 支援編譯程式選項 (/clr:oldSyntax),才能成功將先前的程式代碼範例編譯為 Managed C++。 若要新增 Common Language Runtime 支援編譯程式選項,請遵循下列步驟:
按兩下 [專案],然後按兩下 [ <ProjectName> 屬性]。
注意
<ProjectName> 是專案名稱的佔位元。
展開 [ 組態屬性],然後按兩下 [ 一般]。
在右窗格中,按兩下即可在 Common Language Runtime 支援項目設定中選取 [Common Language Runtime 支援]、[舊語法] (/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 Forms 應用程式] [.NET]。
在 [名稱] 方塊中輸入KB307398,在 [位置] 方塊中輸入
C:\
,然後按兩下 [確定]。在 [設計] 檢視中開啟 Form1 窗體,然後按 F4 開啟 [屬性 ] 視窗。
在 [ 屬性] 視窗中,展開 [ 大小] 資料夾。 在 [ 寬度] 方塊中,輸入 700。 在 [ 高度] 方塊中,輸入 320。
將一個 ListBox 控制件和六個按鈕控制項新增至 Form1。
注意
若要檢視工具箱,請單擊 [檢視] 功能表上的 [工具箱]。
在 [屬性] 視窗中,變更 [位置]、[名稱]、[大小]、[TabIndex] 和這些控件的 [文字] 屬性,如下所示:
控制識別碼 Location 名稱 大小 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 開啟 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 支援服務。 如需如何在 managed extensions for C++ 中建立 Windows 窗體的詳細資訊,請參閱 ManagedCWinFormWiz
Visual Studio .NET 說明中的範例。