C++で入出力ストリームの使い方を知っていれば、あらゆるタイプの入出力デバイスを扱うことができます。
C++ では、ストリーム演算子 >> と << を使用して入力ストリームと出力ストリームを使用することで、ファイルの読み取りと書き込みを行うことができます。ファイルを読み書きするとき、これらの演算子はハードドライブ上のファイルを表すファイルクラスのインスタンスに適用されます。このストリームベースのアプローチには大きな利点があります。C++の観点からは、読み書きの対象がファイルであろうと、データベースであろうと、コンソールであろうと、ネットワーク経由で接続している他のコンピュータであろうと関係ありません。したがって、ストリーム演算子を使ってファイルに書き込む方法を知っていれば、他の分野にも転用できます。
入出力ストリームクラス
C++ 標準ライブラリには、 ios_base クラスが用意されています。このクラスは、 basic_ofstream basic_ifstream、すべてのI/Oストリームの基本クラスとして機能します。この例では、文字の読み取り/書き込みに特殊な型ifstreamとofstreamを使用します。
ofstream: 挿入演算子<<によって実現されるファイルストリームとその能力を出力します。ifstream: 入力ファイルストリームと、抽出演算子>>によって実現されるその能力。
どちらの型もヘッダーファイル <fstream> 定義されています。
ios_baseから継承されたクラスは、データそのものとは完全に切り離され、書き込み時にはデータレシーバーとして、読み込み時にはデータソースとして扱うことができます。このオブジェクト指向のアプローチにより、以下のような概念を簡単に実装することができます。
簡単な例
このルーチンは非常にシンプルで、書き込み用のofstreamと読み込み用のifstreamをインスタンス化します。
#include <iostream> // cout, cin, cerr etc...#include <fstream> // ifstream, ofstream#include <string>int main()std::string sFilename = "MyFile.txt";/******************************************* WRITING *******************************************/std::ofstream fileSink(sFilename); // Creates an output file streamif (!fileSink) {std::cerr << "Canot open " << sFilename << std::endl;exit(-1);fileSink << "Hello Open Source World!" << std::endl;/******************************************* READING *******************************************/std::ifstream fileSource(sFilename); // Creates an input file streamif (!fileSource) {std::cerr << "Canot open " << sFilename << std::endl;exit(-1);else {// Intermediate bufferstd::string buffer;while (fileSource >> buffer)std::cout << buffer << std::endl;exit(0);
コードは GitHub 見ることができます。コンパイルして実行すると、以下のような出力が得られるはずです:
これは簡略化された初心者向けの例です。このコードを自分のアプリケーションで使いたい場合は、以下の点に注意してください:
- ファイル・ストリームは、プログラムの終了時に自動的に閉じられます。実行を続けたい場合は、close() メソッドを呼び出して手動で閉じる必要があります。
- これらのファイル・ストリーム・クラスは basic_iosを継承し、! 演算子をオーバーライドしています。これにより、ストリームがアクセス可能かどうかの簡単なチェックを行うことができます。 cppreference.com 、このチェックが成功した場合の概要と、さらなるエラー処理を実装することができます。
- デフォルトでは、ifstreamは空白で停止し、それをスキップします。 EOF 達するまで1行ずつ読むには、
getline(...)メソッドを使用します。 - バイナリファイルを読み書きするには、コンストラクタに
std::ios::binaryフラグを渡します。
システムの視点から書く
ファイルに書き込む場合、データはシステムのメモリ書き込みバッファに書き込まれます。システムがシステムコール 受信すると、このバッファの内容がハードディスクに書き込まれます。このため、システムに知らせずにUSBメモリーをアンマウントしてはいけません。通常、デーモンは定期的にsyncを呼び出しますが、安全のために手動でsync()を呼び出すこともできます:
#include <unistd.h> // needs to be includedsync();
まとめ
C++でのファイルの読み書きはそれほど複雑ではありません。しかも、入出力ストリームの扱い方を知っていれば、あらゆるタイプの入出力デバイスの扱い方も知っていることになります。さまざまな入出力デバイスに対応したライブラリを使えば、ストリーム演算子を簡単に使うことができます。このように、入出力ストリームの流れを知っておくことは、あなたにとって有益なのです。





