INIファイルからGetPrivateProfileString()で文字列を取得する際、
バッファのサイズはどのくらい用意しておくべきものなのでしょうか。
Win95系ではINIファイル自体が32KB(64KB?)までと聞いたことがありますが、
2000以降での一つのエントリの最大文字数を知りたいと思っています。
ファイルパス文字列のMAX_PATHのように、
最大サイズは決まっているのでしょうか。
それとも、こちらで適当に決めてしまって、それ以上の文字列が入っていた際には
切り捨ててしまったりエラー対応をしたりするしかないのでしょうか。
みなさんはどのようにされていますでしょうか。
よろしくお願いいたします。
バッファサイズの最大値は把握していませんが、バッファが足りるように
なるまで、少しずつバッファサイズを増やしながら取得する、という方法は
いかがでしょうか?
MFCのCString::LoadString()のコードが参考になると思います。
# CWinApp::GetProfileString()では4096が最大になっていますが
>バッファのサイズはどのくらい用意しておくべきものなのでしょうか
読み込もうとしている文字列の長さ(^^;。
とは言ってもこの関数では読み込む文字列の長さをあらかじめ取得できないから困るん
ですよね。
自分も前から「この関数おかしい」と思ってました。ちゃんと?するなら、書き込み時
に書き込んだ
長さを他のキーに保存しておいて、それを読んでバッファを確保してから読み込むと
か?
>それとも、こちらで適当に決めてしまって、それ以上の文字列が入っていた際には
>切り捨ててしまったりエラー対応をしたりするしかないのでしょうか。
私的な結論のべると、長くなる可能性のある文字列を::WritePrivateProfileStringや
::GetPrivateProfileStringなどで保存したり読んだりする事自体が間違いかと思いま
す。
(例:テキストエディタ作ってその読み込むテキストデータ
を::GetPrivateProfileStringで再現する人はいません)
MFC使ってるなら、そのようなオブジェクトはシリアライズするべきです。
自分なら、::GetPrivateProfileString使う場合は最大長をMAX_PATHに決めておいて、
それ以上の長さになる可能性のある文字列はシリアル化などで再現します。
あと質問する時は環境を書いて下さいね。ないと答えにくいです。
>ファイルパス文字列のMAX_PATHのように、
>最大サイズは決まっているのでしょうか。
ファイルパスはMAX_PATH(260)超えられるよ。
UNC表記にすれば32,000文字まで。
INIファイルのファイルサイズを取得し、
その値を取得サイズに設定すれば
取得サイズ<INIファイルのサイズ
というふうになることはありえないのではないでしょうか?
と こんな単純な方法じゃダメですか?;
INIファイルの内容はそのアプリケーションの仕様で決定されるはずなので
アプリケーションの仕様として各項目の最大長をきちんと決めてしまえば良いのではないか
と思います。最大長を決めてそれを超えた場合の対処も仕様としてきちんと定義すれば良
いわけです。最大長を超えた場合はそれ以降は無視と言うのも仕様と言えば仕様。
全く無いとは言いませんけれど、最大長を無制限にしなくてはいけない要件と言うのは殆
ど無いと思いますので私的にはそれで良いと思います。
みなさん、解説ありがとうございます。
やはり厳密にやろうと思ったら、バッファサイズを調べて
動的に確保しなおしたりといった対応が必要なのですね。
> # CWinApp::GetProfileString()では4096が最大になっていますが
ソースを見てみたところ、思いっきり直値で書いてありました。
MFCでも特に根拠の無い数字を使っていたのですか。
これにしたがって、GetPrivateProfileString()に渡すバッファサイズは
4096にしておこうと思います。
> アプリケーションの仕様として各項目の最大長をきちんと決めてしまえば
> 良いのではないかと思います。
たしかに、4096文字もあれば、
よほど例外的なパラメータでない限り収まりますし、
それ以降の文字は無視されますと言ってしまっても問題無いです。
それでも収まらない場合は、ともさんの言われるように、
さすがにINIファイル自体を見直すべきでしょうし。
> ファイルパスはMAX_PATH(260)超えられるよ。
> UNC表記にすれば32,000文字まで。
これって、Windowsのアプリケーションにも当てはまるのでしょうか。
GetModuleFileName()などに渡すバッファなど、あちこちで
TCHAR strFilePath[MAX_PATH];
としていますが、これが破綻しているということなのでしょうか?
>> UNC表記にすれば32,000文字まで。
>これって、Windowsのアプリケーションにも当てはまるのでしょうか。
厳密に言うとUNC表記にしたからって32,000文字までのパスが扱えるようになる
ワケではありません。32,000文字のパスを扱うには、ユニコード版の関数を呼び
出して、ファイルパスの先頭に\\?\という文字を追加して、なおかつアクセス先の
ファイルシステムがNTFSである必要があります。その3つの条件がそろって始めて
扱えるパスの最大長が32,000文字となります。
(CFileなどのMFCを使う場合は\\?\という文字の追加は不要)
MAX_PATH以上の長さのパスを扱う必要がある場合は
>TCHAR strFilePath[MAX_PATH];
ではNGですが、長いファイル名に対応したアプリでなければ問題はないです。
(長いパスが来てもそのファイルにアクセス出来ないだけ)
ただ時代を考えれば、ユニコードのアプリならMAX_PATH以上の長さの
パスへの対応を考えた方が良いかもしれません。
> ただ時代を考えれば、ユニコードのアプリならMAX_PATH以上の長さの
> パスへの対応を考えた方が良いかもしれません。
この「MAX_PATH以上の長さ」というのは、
260から一気に32000になるということなのですよね。
そうなると、うかつに何個もスタック上に取るわけにもいかないでしょうし、
いままでの方法が使えなくなってしまいそうです…。
でも、MFCのCWinApp::GetProfileString()も
INIファイルにたとえば「設定フォルダのフルパス名」なんかを保持していたら、
きちんと読み込めないケースが出てくるということですよね。
一度実際にUNC表記に対応したサンプルソースを探して
勉強してみたいと思います。
ありがとうございました。