ファイル処理と I/O (C++/CLI)

.NET Framework を使ったさまざまなファイル操作について説明します。

次のトピックでは、System.IO 名前空間で定義されたクラスを使用してさまざまなファイル操作を実行する方法について説明します。

ディレクトリ内のファイルを列挙する

ディレクトリ内のファイル リストを取得する方法を次のコード例に示します。 また、サブディレクトリも列挙します。 GetFilesGetFiles メソッドと GetDirectories メソッドを使用して、C:\Windows ディレクトリの内容を表示する方法を次のコード例に示します。

// enum_files.cpp
// compile with: /clr
using namespace System;
using namespace System::IO;

int main()
{
   String^ folder = "C:\\";
   array<String^>^ dir = Directory::GetDirectories( folder );
   Console::WriteLine("--== Directories inside '{0}' ==--", folder);
   for (int i=0; i<dir->Length; i++)
      Console::WriteLine(dir[i]);

   array<String^>^ file = Directory::GetFiles( folder );
   Console::WriteLine("--== Files inside '{0}' ==--", folder);
   for (int i=0; i<file->Length; i++)
      Console::WriteLine(file[i]);

   return 0;
}

ファイル システムの変更を監視する

FileSystemWatcher を使用して、作成、変更、削除、名前変更するファイルに対応するイベントを登録する方法を次のコード例に示します。 ディレクトリに対してファイルへの変更を定期的にポーリングするのではなく、FileSystemWatcher クラスを使用して、変更が検出されたときにイベントを発生させることができます。

// monitor_fs.cpp
// compile with: /clr
#using <system.dll>

using namespace System;
using namespace System::IO;

ref class FSEventHandler
{
public:
    void OnChanged (Object^ source, FileSystemEventArgs^ e)
    {
        Console::WriteLine("File: {0} {1}",
               e->FullPath, e->ChangeType);
    }
    void OnRenamed(Object^ source, RenamedEventArgs^ e)
    {
        Console::WriteLine("File: {0} renamed to {1}",
                e->OldFullPath, e->FullPath);
    }
};

int main()
{
   array<String^>^ args = Environment::GetCommandLineArgs();

   if(args->Length < 2)
   {
      Console::WriteLine("Usage: Watcher.exe <directory>");
      return -1;
   }

   FileSystemWatcher^ fsWatcher = gcnew FileSystemWatcher( );
   fsWatcher->Path = args[1];
   fsWatcher->NotifyFilter = static_cast<NotifyFilters>
              (NotifyFilters::FileName |
               NotifyFilters::Attributes |
               NotifyFilters::LastAccess |
               NotifyFilters::LastWrite |
               NotifyFilters::Security |
               NotifyFilters::Size );

    FSEventHandler^ handler = gcnew FSEventHandler();
    fsWatcher->Changed += gcnew FileSystemEventHandler(
            handler, &FSEventHandler::OnChanged);
    fsWatcher->Created += gcnew FileSystemEventHandler(
            handler, &FSEventHandler::OnChanged);
    fsWatcher->Deleted += gcnew FileSystemEventHandler(
            handler, &FSEventHandler::OnChanged);
    fsWatcher->Renamed += gcnew RenamedEventHandler(
            handler, &FSEventHandler::OnRenamed);

    fsWatcher->EnableRaisingEvents = true;

    Console::WriteLine("Press Enter to quit the sample.");
    Console::ReadLine( );
}

バイナリ ファイルを読み取る

次のコード例では、System.IO の名前空間の 2 つのクラス FileStreamBinaryReader を使用して、ファイルからバイナリ データを読み取る方法を示します。 FileStream は実際のファイルを表し、 BinaryReader はバイナリへのアクセスを可能にするストリームへのインターフェイスを提供します。

このコード例は、data.bin という名前のファイルを読み取り、整数をバイナリ形式で含めます。 この種類のファイルの詳細については、「方法: バイナリ ファイルを書き込む (C++/CLI)」を参照してください。

// binary_read.cpp
// compile with: /clr
#using<system.dll>
using namespace System;
using namespace System::IO;

int main()
{
   String^ fileName = "data.bin";
   try
   {
      FileStream^ fs = gcnew FileStream(fileName, FileMode::Open);
      BinaryReader^ br = gcnew BinaryReader(fs);

      Console::WriteLine("contents of {0}:", fileName);
      while (br->BaseStream->Position < br->BaseStream->Length)
         Console::WriteLine(br->ReadInt32().ToString());

      fs->Close( );
   }
   catch (Exception^ e)
   {
      if (dynamic_cast<FileNotFoundException^>(e))
         Console::WriteLine("File '{0}' not found", fileName);
      else
         Console::WriteLine("Exception: ({0})", e);
      return -1;
   }
   return 0;
}

テキスト ファイルを読み取る

StreamReader クラスを使用して、テキスト ファイルを一度に 1 行ずつ開いて読み取る方法を次の例に示します。このクラスは、System.IO 名前空間で定義されています。 このクラスのインスタンスを使用してテキスト ファイルを開いてから、System.IO.StreamReader.ReadLine メソッドを使用して各行を取得します。

このコード例では、テキストが含まれる textfile.txt というファイルを読み取ります。 この種類のファイルの詳細については、「方法: テキスト ファイルを書き込む (C++/CLI)」を参照してください。

// text_read.cpp
// compile with: /clr
#using<system.dll>
using namespace System;
using namespace System::IO;

int main()
{
   String^ fileName = "textfile.txt";
   try
   {
      Console::WriteLine("trying to open file {0}...", fileName);
      StreamReader^ din = File::OpenText(fileName);

      String^ str;
      int count = 0;
      while ((str = din->ReadLine()) != nullptr)
      {
         count++;
         Console::WriteLine("line {0}: {1}", count, str );
      }
   }
   catch (Exception^ e)
   {
      if (dynamic_cast<FileNotFoundException^>(e))
         Console::WriteLine("file '{0}' not found", fileName);
      else
         Console::WriteLine("problem reading file '{0}'", fileName);
   }

   return 0;
}

ファイル情報を取得する

FileInfo クラスのコード例を次に示します。 ファイル名がわかっている場合、このクラスを使用して、ファイル サイズ、ディレクトリ、完全名、ファイルの作成日時や最終更新日時などのファイル情報を取得できます。

このコードは、Notepad.exe 用のファイル情報を取得します。

// file_info.cpp
// compile with: /clr
using namespace System;
using namespace System::IO;

int main()
{
   array<String^>^ args = Environment::GetCommandLineArgs();
   if (args->Length < 2)
   {
      Console::WriteLine("\nUSAGE : file_info <filename>\n\n");
      return -1;
   }

   FileInfo^ fi = gcnew FileInfo( args[1] );

   Console::WriteLine("file size: {0}", fi->Length );

   Console::Write("File creation date:  ");
   Console::Write(fi->CreationTime.Month.ToString());
   Console::Write(".{0}", fi->CreationTime.Day.ToString());
   Console::WriteLine(".{0}", fi->CreationTime.Year.ToString());

   Console::Write("Last access date:  ");
   Console::Write(fi->LastAccessTime.Month.ToString());
   Console::Write(".{0}", fi->LastAccessTime.Day.ToString());
   Console::WriteLine(".{0}", fi->LastAccessTime.Year.ToString());

   return 0;
}

バイナリ ファイルを書き込む

バイナリ データをファイルに書き込む方法を次のコード例に示します。 System.IO 名前空間の 2 つのクラス、FileStreamBinaryWriter が使用されます。 FileStream は実際のファイルを表し、BinaryWriter はバイナリへのアクセスを可能にするストリームへのインターフェイスを提供します。

バイナリ形式の整数を含むファイルを書き込む方法を次のコード例に示します。 このファイルは、「方法 : バイナリ ファイルを読み取る (C++/CLI)」のコードを使用して読み取ることができます。

// binary_write.cpp
// compile with: /clr
#using<system.dll>
using namespace System;
using namespace System::IO;

int main()
{
   array<Int32>^ data = {1, 2, 3, 10000};

   FileStream^ fs = gcnew FileStream("data.bin", FileMode::Create);
   BinaryWriter^ w = gcnew BinaryWriter(fs);

   try
   {
      Console::WriteLine("writing data to file:");
      for (int i=0; i<data->Length; i++)
      {
         Console::WriteLine(data[i]);
         w->Write(data[i]);
      }
   }
   catch (Exception^)
   {
     Console::WriteLine("data could not be written");
     fs->Close();
     return -1;
   }

   fs->Close();
   return 0;
}

テキスト ファイルを書き込む

テキスト ファイルを作成し、StreamWriter クラスを使用してそのファイルにテキストを書き込む方法を次の例に示します。このクラスは、System.IO 名前空間で定義されています。 StreamWriter コンストラクターは、作成されるファイル名を受け取ります。 ファイルが存在する場合、そのファイルに上書きされます (ただし、2 番目の StringWriter コンストラクター引数として True を渡す場合は例外です)。

次に、Write 関数と WriteLine 関数を使用してファイルが保存されます。

// text_write.cpp
// compile with: /clr
using namespace System;
using namespace System::IO;

int main()
{
   String^ fileName = "textfile.txt";

   StreamWriter^ sw = gcnew StreamWriter(fileName);
   sw->WriteLine("A text file is born!");
   sw->Write("You can use WriteLine");
   sw->WriteLine("...or just Write");
   sw->WriteLine("and do {0} output too.", "formatted");
   sw->WriteLine("You can also send non-text objects:");
   sw->WriteLine(DateTime::Now);
   sw->Close();
   Console::WriteLine("a new file ('{0}') has been written", fileName);

   return 0;
}

関連項目

C++/CLI (Visual C++) による .NET プログラミング
ファイルおよびストリーム入出力
System.IO 名前空間