ファイルマッピングとMapViewOfFileについて

このQ&Aのポイント
  • C言語初心者の質問:ファイルマッピングとMapViewOfFileについて教えてください
  • 初心者向けの質問:ファイルマッピングを使用した共有メモリについて詳しく教えてください
  • Windows2000とVC6.0を使用している初心者ですが、ファイルマッピングについて教えてください
回答を見る
  • ベストアンサー

MapViewOfFileについて教えて下さい

C言語の初心者ですが、ファイルマッピングについて教えて頂きたいことがあります。 あるファイルをMapViewOfFileを使用し、複数タスクの共有メモリとして使用中に、 クローズせずに再マッピング(?)みたいなことはできないでしょうか? 例えば、マッピングするAというファイルの内容が、変数A=0、変数B=0、変数C=0、としてOpenFileMapping(FILE_MAP_ALL_ACCESS)されている。 次に、Bというファイルの内容が、Aファイルと変数名は変わらずで、 変数A=1、変数B=1、変数C=1、とします。 ここでAファイルをクローズ(他タスクが参照するかもしれないので)せずに、 AファイルをBファイルの内容にしたいということなのです。 こんなことは、やはりできないのでしょうか? もちろん、Aファイルがマッピングされているので、直接Aを変更すれば良いのですが、 ファイル内容が膨大なため、なんとか再マッピング(?)できればと思ったのです。 OSはWindows2000で、VC6.0になります。 わかりにくい文章で申し訳ございませんが、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#30727
noname#30727
回答No.1

>直接Aを変更すれば良いのですが、ファイル内容が膨大なため 膨大というのはどの程度ですか? 数MBくらいなら、Bファイルを読み込んでおいて、memcpy等でコピーするだけですよね。

pota_1119
質問者

補足

回答ありがとうございます。 ファイルのサイズは、約14MBです。膨大というのは大げさでした。すみません。 ファイルを読み込んで変更する以外は無理なのでしょうか?

その他の回答 (1)

noname#30727
noname#30727
回答No.2

#1です。 >ファイルを読み込んで変更する以外は無理なのでしょうか? 最初の読み込みはBファイルを使い、その後はAファイルを使うようなマッピングが出来なければならないですが、そういう事は出来ません。 VirtualAlloc、AllocateUserPhysicalPages等、SEHを使用して自前で作れないかとも思いましたが、MSDNを読む限りでは、同一ページをプロセス間で共用できそうな気がしませんし、それにSEHを使うなんてマニアックすぎですよね。 MapViewOfFileにFILE_MAP_COPYを指定してAファイルが変更されないようにしても、Win2000だと共有メモリにはならないので、この方法も駄目です。 共有メモリが初期化される事がある以上、なんらかの排他制御と各タスクが再起動するような機能が必要だと想像できます。 再起動には時間がかかる。と思うしか無いと思います。

pota_1119
質問者

お礼

遅れまして申し訳ございません。 2度に渡り解答して頂きありがとうございました。 結局、inthefloiさんの言う通りファイル読み込みmemcpyすることにしました。

関連するQ&A

  • union共同体の使い方…

    typedef union {  A_FILE* aFile;  B_FILE* bFile; }C_FILE; 上記のようにunion共同体で2つの型を 対応するものを作りました。 ファイルをオープンするのに C_FILE file_Open( const char *filename); というI/Fを作りました。 でもファイルをクローズする時に ファイルハンドルを渡そうと思うのですが、 ファイルハンドルの引数をどっちの型が入っても よいようにしたいのですが。 int file_Close(C_FILE.aFile Fp) ←これでは意味がない… int file_Close(C_FILE Fp)  ←こういう使い方は出来ませんよね? ファイルオープン側に実体を持ったままで、 どっちの型が入ってもよいファイルクローズを行う I/Fを作るのは無理なのでしょうか。 やはり実体は呼びだす側にあるべきなのでしょうか?

  • MapViewOfFile() はカウンタを進めない?

    Windows APIの質問です。 PINT GetShareInt() { ____HANDLE hmap = CreateFileMapping( ________INVALID_HANDLE_VALUE, NULL, ________PAGE_READWRITE, ________0, sizeof(int), ________TEXT("Share") ); ____PINT pi = (PINT)MapViewOfFile( ________hmap, FILE_MAP_WRITE, 0, 0, 0); ____CloseHandle(hmap); ____return pi; } こんな感じの関数で変数をプロセス間共有したいのですが、 ファイルマッピングオブジェクトが毎回生成されてしまい、 変数を共有できません。 先にCloseHandleするのは後の処理がUnmapViewOfFileするだけで すむからです。変則的ですが、MapViewOfFile呼び出ししている以上 hmapが指すカーネルオブジェクトは開放されないと思うのですが。 MapViewOfFileがカーネルオブジェクトの内部カウンタを進めていない、 ということでしょうか?それではマルチスレッドで扱えないような気が するのですが、私の認識のどこが間違っているのでしょうか? よろしくご指導お願い申し上げます。

  • 配列をファイルに保存する方法、取り出す方法を教えてください

    (1)配列をファイルに保存する方法 (2)保存した配列をファイルから出す方法 がよく分かりません。教えていただけないでしょうか。恐れ入りますがよろしくお願いいたします。 (1) $a = "あ"; $b = "い"; $c = "う"; を(@hairetuに入れて?)ファイルに保存する方法。(ファイルにすでに保存済のデータがあった場合には、消去したいと考えております。) (2) ファイルを開き、保存されている(@hairetuを取り出し?$a 、$b 、$cに切り分け?)$a 、$b 、$c を再び"あ""い""う""として用いることができるようにする方法 ちなみに、以下のように記述してみたのですが、上手く動作しませんでした。 #####################(1)配列をファイルに保存################# #!/usr/bin/perl $file = "file.dat"; $a = "あ"; $b = "い"; $c = "う"; $d = "え"; ### $a="あ" $b="い" $c="う" を@hairetuに入れたつもりです。 @hensu = ('$a','$b','$c','$d'); ### @hairetuをファイルに保存したつもりです。 open(FILE, "+<$file"); print FILE @hensu; close(FILE); ##############(2)保存した配列をファイルから出す############### ### ファイルを開き、保存されている@hairetuを取り出したつもりです。 open(FILE, "+<$file"); @hensu = <FILE>; ### @hairetuを再び$a $b $cに切り分けようとしているのですが、これでよろしいでしょうか。 foreach $line (@hensu){ ($a,$b,$c,$d) =split(/\,/,$line); } close(FILE); ### 確認のため表示 print $a; print $b; print $c; print $d; ### これを実行すると、「あいうえ」でなく「$a$b$c$d」と表示されてしまいます。何処が間違っているのか教えていただけると幸いです。

    • ベストアンサー
    • CGI
  • C言語のローカル変数の使い方について質問です。

    C言語の変数に関しての質問です。 グローバル変数を使わずに、関数内で宣言したローカルの変数を別のソースファイルで使用することって可能ですか? 例えば、a.cというソースファイルと、b.cというソースファイルがあります。 a.cの関数内で"FILE *fp;"と宣言したローカル変数を、b.cの関数内で共有して使うことはできるのでしょうか。 また、"fp"に直接アクセスはできなくても、間接的にアクセスできる方法があれば教えてください。 下に記述しているのは例え用に適当に書いたプログラムです。 --------------------- a.cのソースファイル --------------------- void Temp(void) { char file_name[128] = {}; errno_t error; FILE *fp; // ←この変数を別のソースで使いたいです scnaf_s("%s", file_name, 128); if(error = fopen_s(&fp, fname, "rb") != 0) { printf("ファイルがオープンできません"); return 0; } fclose(fp); } --------------------- b.cのソースファイル --------------------- void Temp2(void) { int size; // ここでa.cのTemp関数で宣言されている"fp"を使いたい fseek( fp, 0, SEEK_END ); fsize = ftell( fp ); fseek( fp, 0, SEEK_SET ); }

  • VBAを使用して、ブックからブックを開く

    Excel2000を使用しております。 VBAを使用してA、B、Cの三つのBookを作成しました。 上記3ッのファイルとは別にINDEX用のBookを作成し、 INDEXから、A、B、C、のファイル名を指定し、ファイルを 開ける様にしました。    A、B、Cのいずれかのファイルを開いた後、INDEX用の BOOKを自動で閉じたいのですがうまく行きません。  どなたかご教授願います。 A、B、CにOpenEventを設定し、インデックス用BOOKを閉じようと すると、閉じる事は可能なのですが、それ以降のOpenEventのマクロが 進みません。 逆にINDEX用のBOOKにCloseを入れても閉じてくれません。 INDEXのCloseはA、B、CのファイルをOpenの後にCloseを 入れてます。  どなたかご教授願います。

  • リエントラント関数

    はじめまして。 複数のタスクで利用されるような関数を作成しようと思っています。 この関数をFuncAとします。 void FuncA() {   int a;   int b;   int c;   処理1;   処理2;   処理3;   処理4; } タスクは優先度低のタスクAと優先度高のタスクBがあるとします。 タスクAがこのFuncAの処理2を行っている最中に、 タスクBがこのFuncAを呼び出すとタスクBで先にFuncA処理をしてから、 タスクAに戻って続きの処理3を行うと思います。 このとき、タスクAで使用していたローカル変数a,b,cはどっかに退避されているのでしょうか?

  • 改行コードの挿入について[タグチェッカー]

    現在、UNIXでhtmlタグのチェッカーを作っています。 たとえば、 <a><b> <c> というhtmlファイルがあるとします。(<a>,<b>,<c>などのタグがあるとする) これを配列に <a> <b> <c> という風に入れたいのですが、現在は #!/usr/bin/perl @allfile = (); open(f, "test.html"); while($file = <f>){     chomp $file;     if ($file =~ /^<.*>/){ # allfileにタグを1つずつ格納する         @allfile = (@allfile,$file);     } } close(f); としていてif ($file =~ /^<.*>/) の後に改行コードを入れたいのですがどうすれば入れれますか?

    • ベストアンサー
    • Perl
  • 共有メモリへのマッピング(MapViewOfFile)について

    共有メモリについて(特にMapViewOffileについて)教えてください。 ある構造体と、あるデータAを共有メモリへマッピングしたい考えています。 構造体は、 typedef struct _Data { int length; long data; char mIntArrayData[256]; } Data; データAは、short型の配列(要素数はx*y*z,x,y,zはcsvファイル等から読み込む)で、サイズをdatasize = sizeof(short) * x * y * z;とします。 この2つを使って、 両方のデータを long AllDataSize = sizeof(Data) + datasizeとしました。 このサイズを使って、共有メモリのマップハンドルを hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,PAGE_READWRITE,AllDataSize,MAPPED_FILE_NAME); (MAPPED_FILE_NAMEは、 メモリマップドファイルの名前) で、生成しました。 生成はできたのですが、データAにアクセスするための下記のような時にマッピングに失敗してしまいました。 DWORD dwOffset = sizeof(DATA); short *pData = (short *)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, dwOffset, Bytes); (Bytesはマッピングしたいバイト数でsizeof(short)の倍数) 次のようなDATAにアクセスするマッピングには成功しています。 DWORD dwOffset = 0; DATA *pDATA = (DATA *)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, dwOffset, sizeof(DATA)); 色々なサイト等を調べて、考えてみたのですが、怪しいところはdwOffsetと、CreateFileMappingで、マッピングしたい全体のファイルサイズを、構造体とデータAのサイズの単純な足し算としているところと考えています。ただ、はっきりとした答えが全くわからないので、どうか御教授お願いします。

  • Fortranの出力の改行について

    Fortran超初心者です。 test1.csvのファイルには、x,yの変数がずっと続いています。 test2.datのファイルには、a,bの変数がずっと続いています。 この2つのファイルの変数を元に、d,eの値を求め、それをtest3.csvというファイルに出力したいのです。 test1.csvとtest2.datの計算はできていたのですが、test3.csvの出力は最後の計算結果のみしか出力されていません。 多分毎回出力はしているのですが、計算を繰り返すと上書きされ消えてしまうという仕組みになっているのだと思います。 どうやったら上書きされずに、csvファイルの次の行に次のデータを入力できますか? 以下私が考えたFortran90のプログラムです。 open (10, file='test1.csv', status='old')  do   read (10, *, iostat=ios) x, y   open (11, file='test2.dat', status='old')   do    read (11, *, iostat=jos) a, b    d = x +a    e = y + b    if (jos .lt. 0) exit   enddo   open (12, file='test3.csv', status='replace')   write (12, *) x, y, a, b, d, e   close (12)   close (11)   if (ios .lt. 0) exit  enddo close (10) 本当に始めたばかりで、いまいち意味の分かっていない部分もあるのですが、問題点を指摘してくれたら助かります。 わかりにくいので、具体的に少し書くと、 test1.csvには 1,2 9,3 6,4 とデータが続くとします。 test2.datには 80,50 10,20 90,60 とデータが続くとします。 test3.datには 1,2,80,50,81,52 1,2,10,20,11,22 1,2,90,60,91,62 9,3,80,50,89,53 9,3,10,20,19,23 9,3,90,20,99,23 6,4,80,60,86,64 6,4,10,20,16,24 6,4,90,20,96,24 と出力されるようにしたいのです。 実際のデータや変数名も違いますが、プログラムの構造は同じです。 よろしくおねがいします。

  • fputで出力した文字列を改行するには?

    PHP初心者です。 いくつかの文字列変数をテキストファイルに書き出す処理を行いたいのですが、うまく動作してくれません。 文字列変数 $str_a, $str_b, $str_cをカンマで区切ってテキスト1行でファイルに書き出しています。 $str = $str_a . ',' . $str_b . ',' . $str_c . '\\r\\n'; fputs($fp, $str); 上の2行がループで数回呼ばれた後、ファイルをクローズしているのですが、実際に作成されたテキストファイルを見ると a1,b1,c1\r\na2,b2,c2\r\n....みたいに改行が入らず"\r\n"という文字列があるだけです。希望しているのは a1,b1,c1 <-ここで改行 a2,b2,c2 <-ここも改行 という結果なのですが.... よろしくご教授お願いいたします。

    • ベストアンサー
    • PHP

専門家に質問してみよう