VC6 MFC です。
ファイルから行単位で読み込む処理に関してなのですが、
CFile file;
file.Open(...);
CArchive ar(&file, CArchive::load);
ar.ReadString(...);
と
CStdioFile file;
file.Open(...);
file.ReadString(...);
って、結局やってることは同じなのでしょうか?
それとも、両者を使い分けるケースもあるのでしょうか?
なぜCStdioFileにはReadString()があるのに、CFileには無いのでしょうか?
もしくは逆に考えると、CArchive経由でCFileから行単位で取得できるのに、
なぜCStdioFileにはReadString()が追加で実装されているのでしょうか?
クラス図を見よう
CObject → CFile → CStdioFile と派生していることが図示されている
(矢印が反対?まあいいや)
つまり CFile に比べて CStdioFile は「目的を絞った分、高機能」ということだ
CStdioFile : テキスト入出力専用(だから改行までの入出力関数が有る)
CFile : テキストバイナリ両方(だから改行までの入出力関数は無い)
CArchive と CStdioFile は使用目的が異なる。
たまたま「改行までの入出力関数を持っている」という点だけが同じだが
使用される状況などはまったく違うので同一視しないほうがいい
あり...
CFile と CStdioFile の違いって、直接ファイルに読み書きするか、バッファを介する
かの違いじゃなかったでしたっけ?
で、CStdioFileはバッファを介するからこそ、改行コード(CR + LF <-> LF)の変換がで
きるということだったような気がします。
CFileでテキストの読み書きできます(ただし改行コードの変換不可)し、CStdioFileでバ
イナリファイルの読み書きは何の問題もありません。
クラスの派生関係から考えるなら、
CStdioFileはCFileに便利な機能を追加して使い易くしたものと
考えてよろしいかと思います。
CFileにReadStringが無いのはCFileがCStdioFileを使うような場面以外でも
使う時にReadStringは必須では無いとMFCの設計者が考えたからでしょうね。
基本クラスはシンプルに作っていろいろな場面で使えるように作ると思うので。
この辺は実際に自分でクラス設計をやってみるとどう組み立てると無駄が
減らせるかとか、メンテナンス性が上がるかとかの兼合いと言うのがわかると
思います。CStdioFileはCFileの機能を内包していますからCFileが出来る事は
全部出来ます。その上で更に便利な機能を追加して実装しています。
CStdioFileでやっていることを全て自分で実装出来るならCFileで同じ事は
可能だと思いますけれど、既にあるわけなのでそっちを使った方がリーズナブル
という話になるかと思います。
CArchiveに関しては概念が違うと思うのでCStdioFileをは一緒にしない方が
良いでしょう。この辺はオブジェクト指向でクラスを考える時にどうモデル化
するかと言う話もあると思うのでどうして?と言う問いに答えるのは結構
面倒かもしれませんね。
オブジェクト指向とかクラス概念とかこの辺を勉強されると
色々納得できるのではないかなぁと思います。
結局はクラスの設計をした人の思想が表れていると思いますので。
tetrapodさん、bunさん、PATIOさん、解説ありがとうございます。
> クラスの派生関係から考えるなら、
> CStdioFileはCFileに便利な機能を追加して使い易くしたものと
> 考えてよろしいかと思います。
ということは、CStdioFileは
CFileとCArchiveを使って行単位で読み込む処理を
CArchiveを使わずに行うことができる便利なクラス
という解釈でもよいものなのでしょうか。
他に追加されている関数も無いようなのですが。
たとえば「ログをファイルに行単位で出力していく」という処理を作る場合、
MFCのクラスだと、CStdioFileのみでやってしまうものなのでしょうか?
それともCArchiveを組み合わせるべきなのでしょうか?
私の記憶では、
CFile は 低水準入出力 をMFC化したもので
CStdioFile は ストリーム入出力 をMFC化したものだったはずです。
それぞれ、MSDNを[低水準入出力][ストリーム入出力]で検索すると、説明が出て
きます。
(連続した)大きなファイルの場合、バッファリングした方がHDDの先読みを有効
利用できるので有利です。
CArchiveはシリアル化をサポートするクラスであって、そのためのサポートとし
て、ReadString(), WriteString()があると思った方がいいです。
一般にファイル操作を行うクラスは、
CFile, CStdioFile
です。
以上より、CStdioFileのみでやってしまうのが正解だと思います。
解説ありがとうございます。
> 一般にファイル操作を行うクラスは、
> CFile, CStdioFile
> です。
CMemFileなどと違って、CFileとCStdioFileはどちらもディスクファイルなので、
両者を使い分ける境界線がまだちょっと理解できていませんが、
「低水準入出力」をあえて使いたいと意識したこともありませんし、
通常はディスクファイル用のインスタンスを作るところでは
CFileではなくCStdioFileを使っておいたほうがよいのでしょうかね。
済マークは付けさせていただきますが、
ツッコミどころがあれば指摘していただけると嬉しいです。
ありがとうございました。