メモリマップドファイルをファイルに書き込む          <TOP>


CreateFileMapping 指定されたファイルに対するファイルマッピングオブジェクトを作成またはオープン
MapViewOfFile ファイルビューをマッピング
UnmapViewOfFile ファイルのマップビューをアンマップ
CreateFile 指定したファイルをオープンし、デバイスハンドルを返す
CloseHandle オープンされているオブジェクトハンドルをクローズ
GetFileSize ファイルのサイズをバイト単位で取得
OpenFileMapping 名前付きファイルマッピングオブジェクトをオープン
FlushViewOfFile マップトファイルのビュー内にある、指定された範囲のデータをディスクに書き込む
SetFilePointer 開いているファイルのポインタを移動
WriteFile データをファイルに書き出す
FillMemory メモリブロックを指定の値で初期化
 

書き込まれたファイルの中をバイナリダンプで見てみる。

 

'================================================================
'= メモリマップドファイルをファイルに書き込む
'=    (FlushViewOfFile.bas)
'================================================================
#include "Windows.bi"

' 指定されたファイルに対するファイルマッピングオブジェクトを作成またはオープン
Declare Function Api_CreateFileMapping& Lib "Kernel32" Alias "CreateFileMappingA" (ByVal hFile&, ByVal lpFileMappigAttributes&, ByVal flProtect&, ByVal dwMaximumSizeHigh&, ByVal dwMaximumSizeLow&, ByVal lpName$)

' ファイルビューをマッピング
Declare Function Api_MapViewOfFile& Lib "Kernel32" Alias "MapViewOfFile" (ByVal hFileMappingObject&, ByVal dwDesiredAccess&, ByVal dwFileOffsetHigh&, ByVal dwFileOffsetLow&, ByVal dwNumberOfBytesTolMap&)

' ファイルのマップビューをアンマップ
Declare Function Api_UnmapViewOfFile& Lib "Kernel32" Alias "UnmapViewOfFile" (ByVal lpBaseAddress&)

' 指定したファイルをオープンし、デバイスハンドルを返す
Declare Function Api_CreateFile& Lib "Kernel32" Alias "CreateFileA" (ByVal lpFileName$, ByVal dwDesiredAccess&, ByVal dwShareMode&, lpSecurityAttributes As Any, ByVal dwCreationDisposition&, ByVal dwFlagsAndAttributes&, ByVal hTemplateFile&)

' オープンされているオブジェクトハンドルをクローズ
Declare Function Api_CloseHandle& Lib "Kernel32" Alias "CloseHandle" (ByVal hObject&)

' ファイルのサイズをバイト単位で取得
Declare Function Api_GetFileSize& Lib "Kernel32" Alias "GetFileSize" (ByVal hFile&, lpFileSizeHigh&)

' 名前付きファイルマッピングオブジェクトをオープン
Declare Function Api_OpenFileMapping& Lib "Kernel32" Alias "OpenFileMappingA" (ByVal dwDesiredAccess&, ByVal bInheritHandle&, ByVal lpName$)

' マップトファイルのビュー内にある、指定された範囲のデータをディスクに書き込む
Declare Function Api_FlushViewOfFile& Lib "kernel32" Alias "FlushViewOfFile" (lpBaseAddress As Any, ByVal dwNumberOfBytesToFlush&)

' 開いているファイルのポインタを移動
Declare Function Api_SetFilePointer& Lib "Kernel32" Alias "SetFilePointer" (ByVal hFile&, ByVal lDistanceToMove&, lpDistanceToMoveHigh&, ByVal dwMoveMethod&)

' データをファイルに書き出す
Declare Function Api_WriteFile& Lib "Kernel32" Alias "WriteFile" (ByVal hFile&, lpBuffer As Any, ByVal nNumberOfBytesToWrite&, lpNumberOfBytesWritten&, lpOverlapped As Any)

' メモリブロックを指定の値で初期化
Declare Sub FillMemory Lib "Kernel32" Alias "RtlFillMemory" (Destination As Any, ByVal Length&, ByVal Fill As byte)

#define PAGE_READONLY &H2               'コミット済みのページ領域に対する読み取りアクセスを許可
#define PAGE_READWRITE &H4              'コミット済みのページ領域に対する読み取りアクセスと書き込みアクセスの両方を許可
#define FILE_MAP_READ &H4               '読み込み専用モード
#define FILE_MAP_WRITE &H2              '読み書きモード
#define FILE_MAP_COPY &H1               '上書きモード
#define GENERIC_READ -2147483648        '読み込みモード(&H80000000)
#define GENERIC_WRITE &H40000000        '書き込みモード
#define OPEN_ALWAYS 4                   'ファイルをオープンする(存在しない場合作成)
#define OPEN_EXISTING 3                 'ファイルをオープンする(存在しない場合失敗)
#define CREATE_ALWAYS 2                 '新しいファイルを作る(存在する場合には上書)
#define FILE_ATTRIBUTE_NORMAL &H80      '他のファイル属性を持たない
#define FILE_BEGIN 0                    'ファイルポインタを先頭に
#define FILE_CURRENT 1                  '現在のファイルポインタの値が開始点
#define FILE_END 2                      '現在ファイルの終端の位置が開始点
#define mapname "maptest"
#define strFilename "maptest.dat"

Var Shared Button1 As Object

Button1.Attach GetDlgItem("Button1") : Button1.SetFontSize 14

Var Shared Addr As Long
Var Shared lMap As Long

'================================================================
'=
'================================================================
Declare Sub makefile ()
Sub makefile()
    Var File As Long
    Var LowSize As Long
    Var HighSize As Long
    Var Dat As Long
    Var WriteSize As Long
    Var Ret As Long
    
    File = Api_CreateFile(strFilename, GENERIC_WRITE, 0, ByVal 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
    
    If File = 0 Then
        A% = MessageBox("", "ファイル作成に失敗", 0, 2)
        Exit Sub
    End If
    
    '10MBのファイルを作成
    LowSize = 1024 ^ 2 * 10
    HighSize = 0

    Ret = Api_SetFilePointer(File, LowSize, HighSize, FILE_BEGIN)
    Ret = Api_WriteFile(File, Dat, Len(Dat), WriteSize, ByVal 0)
    Ret = Api_CloseHandle(File)
End Sub

'================================================================
'=
'================================================================
Declare Sub Button1_on edecl ()
Sub Button1_on()
    Var File     As Long
    Var Size     As Long
    
    '10MBのファイルを作成
    makefile
    
    File = Api_CreateFile(strFilename, GENERIC_READ Or GENERIC_WRITE, 0, ByVal 0, OPEN_EXISTING, 0, 0)
    
    If File = -1 Then
        A% = MessageBox("", "CreateFile で失敗", 0, 2)
        Exit Sub
    End If
    
    Size = Api_GetFileSize(File, 0)

    lMap = Api_CreateFileMapping(File, ByVal 0, PAGE_READWRITE, 0, Size, mapname)
    Ret = Api_CloseHandle(File)
    
    If lMap = 0 Then
        A% = MessageBox("", "CreateFileMapping で失敗", 0, 2)
        Exit Sub
    End If
    
    Addr = Api_MapViewOfFile(lMap, FILE_MAP_WRITE, 0, 0, 0)
    
    If Addr = 0 Then
        A% = MessageBox("", "MapViewOfFile で失敗", 0, 2)
        Exit Sub
    End If
    
    '一気に "x" で初期化する
    FillMemory ByVal Addr, Size, Asc("x")
    
    'ファイルに書き込み
    Ret = Api_FlushViewOfFile(Addr, 0)
    
    Ret = Api_UnmapViewOfFile(Addr)
    Ret = Api_CloseHandle(lMap)

    A% = MessageBox("", "「x」で初期化し、" & Chr$(13, 10) & "ファイルに書き込みました。", 0, 2)
End Sub

'================================================================
'=
'================================================================
While 1
    WaitEvent
Wend
Stop
End