アプリ版:「スタンプのみでお礼する」機能のリリースについて

Win98を対象としたファイル結合ソフトを作りました。
newでメモリ確保してaとbを結合しますが、結合後に2Gになるものなら空き領域が2Gぐらい必要なのでそのような場合には使えないソフトとなってしまいました。
空き領域がほとんど無くて、1.9Gのaに0.1Gのbを結合してaを上書きする感じで結合させたいのですが、アセンブラ以外の方法を教えてください。

A 回答 (5件)

1.256バイトのバッファを確保する


2.cを新規ファイルでライトオープン
3.aをリードオープン
4.aからバッファに256バイト読んでみる
5.読み込めたバイト数がゼロなら8へ
6.読み込めたバイト数だけバッファをcにライトする
7.4に戻る
8.aをクローズする
9.bをリードオープン
10.bからバッファに256バイト読んでみる
11.読み込めたバイト数がゼロなら14へ
12.読み込めたバイト数だけバッファをcにライトする
13.10に戻る
14.bをクローズする
15.cをクローズする
16.aをファイル削除する
17.cをaにリネームする
18.1で確保したバッファを開放する

これで、aとbがどれだけ大きくても大丈夫。使うメモリは256バイトだけ。

この回答への補足

ありがとうございます。
その方法だとendoffile()かtrunc()何かでaのサイズを減らしてゆかなくてはなりません。減らす方法も僕には思いつきません。
HDDの空きは2.1Gで、既に1.9Gのaと0.1Gのbが既存だとして、aにbを結合させるソフトです。

補足日時:2007/03/27 02:55
    • good
    • 0

追記



「MS-DOSプロンプト」を起動して、黒いDOS窓で
COPY /B a+b c
DEL a
REN c a
の3行を打つと、No.1の回答で説明したプログラムと同じ事をします。

「実はファイル結合ソフトは要らなかった」と言うオチ。

因みに
COPY /B a+b+c+d+e f
DEL a
REN f a
で5つのファイルを結合できたりもする。

この回答への補足

「実はコンベンショナルメモリが足りなかった」と言うオチ。
WinVistaなど知りませんが、黒いDOS窓で2Gを扱うのは無理ではないでしょうか?
しかし結合後のファイルサイズが500MBぐらいのものなら僕が作ったソフトより黒いDOS窓でCOPYした方がなぜか高速なのです。

補足日時:2007/03/27 03:03
    • good
    • 0

普通は、アペンドモードで a をオープンしたりしますが。


Cなら、
fopen("filename", "a"); // テキストファイル
fopen("filename", "ab"); // バイナリファイル

C++なら、
ofstream("filename", ios::app);
※テキストファイルならOK,バイナリファイルでやったことはないので不明

これで、a をオープンして、ひたすら、write すればOKです。

この回答への補足

ありがとうございます。
僕がやりたいことができている結合ソフトがありました。
そのソフトはたぶんアペンドモードでオープンしていたのかもしれませんがアペンドモードのことを忘れていて、作者はたぶんアセンブラを知らないのに何でそんなことが可能なのか不思議でした。

補足日時:2007/03/27 18:10
    • good
    • 0

★『メモリ・マップドファイル』という技術を利用するのは?どう。


・これはファイルをメモリのように扱える方法でメモリコピーの関数で追加など出来ます。
 今回のように巨大なファイルやディスク容量に限りがある場合には有効な手段だと私は思います。
・『巨大ファイルの合併』方法としては、
 (1)1.9GバイトのファイルAを『メモリ・マップドファイル』に割り付ける。→α
 (2)0.1GバイトのファイルBを『メモリ・マップドファイル』に割り付ける。→β
 (3)αデータのポインタ位置を最後に移動する。→α += 1.9Gのサイズ分;
 (4)αデータのポインタ位置にβデータをメモリ・コピー関数で結合する。→MemoryCopy(α,β,0.1Gのサイズ);
 (5)α、βの『マップドファイル』のメモリ割り付けを解除する。→普通のファイルに戻る。
 (6)巨大ファイル 1.9Gバイト(α) に 0.1Gバイト(β)のデータが結合する。
・これならばメモリ確保しなくても良いし、1.9Gバイトのファイルに上書きした感じで結合されます。

最後に:
・『メモリ・マップドファイル』は『CreateFileMapping』API関数で行えますが、MFCなら専用のクラスが
 あります。MFC は使ったことがないため詳しくありませんが、ファイルをメモリに変換する方法が今回の
 『メモリ・マップドファイル』の事です。
http://www.fsinet.or.jp/~madcap/memmap.html→『メモリマップドファイル』
http://homepage2.nifty.com/DSS/WinSys/Win/FileMa …→『メモリマップドファイル』
http://www.h6.dion.ne.jp/~game296o/DXCLS_MemoryM …→『メモリマップドファイルクラス』
・すべて C/C++ で実装できます。アセンブラ以外です。ただ1点、『メモリ・マップドファイル』で 1.9 G
 の巨大ファイルが扱えたかどうか良く覚えていません。上限は 1G バイトだったような気が…。
・もしも、1G 以上が扱えなかった場合は、回答者 No.3 さんの方法が有効になります。
 追加モードで 1.9G バイトのファイルを開き、0.1G バイトのファイルを読み込み専用でオープンして
 単純に fread、fwrite して合併すれば良いでしょう。
・以上です。参考に!

参考URL:http://www11.ocn.ne.jp/~ikalu/win32api/0014.html
    • good
    • 0
この回答へのお礼

(1)~(6)の手順を見るとできそうですね。
試してみます。

お礼日時:2007/04/06 04:37

> ANo.4


メモリマップトファイルの場合は後からサイズ拡張できないので
あらかじめファイルサイズを2GBにしておかなければならないのと、
Win9X系ではファイル全体が共有メモリ領域(1GB)にマッピング
できなければいけないという制約があったりして、この場合には
適用できないかと。NT/2k系だと部分的にマッピングしたりとか
してできるとは思いますが。
やっぱりNo3の方の追加モードがベストな手段だと思います。
    • good
    • 0
この回答へのお礼

あらかじめファイルサイズを2GBにしておかなければならないということではメモリマップトファイルは今回は使えませんね。

お礼日時:2007/04/06 04:33

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!