Namespace System Namespace IO /* ほんとはmiscに入れるかかファイルを分けたほうがいいかもしれないが一先ず実装 */ Enum FileOptions Asynchronous DeleteOnClose Encrypted None RandomAccess SequentialScan WriteThrough End Enum Class FileStream Inherits Stream handle As HANDLE /* ファイルハンドルからこれらを取得できれば、これらは入らないが 今のところは不明なので自前で実装するしかない */ filePath As String fileMode As DWord fileAccess As DWord fileShare As DWord fileOptions As DWord /* 現在は未使用 */ /*Overlapped As OVERLAPPED*/ Public /* コンストラクタ.NETと同じように実装は難しい、一先ず動くものを実装したが変更が必要だと思う */ Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare, options As FileOptions) Dim ac As DWord Dim mo As DWord Dim sh As DWord Dim op As DWord Select Case access Case FileAccess.Read ac=GENERIC_READ Case FileAccess.ReadWrite ac=GENERIC_READ or GENERIC_WRITE Case FileAccess.Write ac=GENERIC_WRITE End Select Select Case share Case FileShare.DeleteFile sh=FILE_SHARE_DELETE Case FileShare.None sh=0 Case FileShare.Read sh=FILE_SHARE_READ Case FileShare.ReadWrite sh=FILE_SHARE_READ or FILE_SHARE_WRITE Case FileShare.Write sh=FILE_SHARE_WRITE End Select Select Case mode Case FileMode.Append mo=OPEN_ALWAYS Case FileMode.Create mo=CREATE_ALWAYS Case FileMode.CreateNew mo=CREATE_NEW Case FileMode.Open mo=OPEN_EXISTING Case FileMode.OpenOrCreate mo=OPEN_ALWAYS Case FileMode.Truncate mo=TRUNCATE_EXISTING End Select Select Case options Case FileOptions.Asynchronous op=FILE_FLAG_OVERLAPPED Case FileOptions.DeleteOnClose op=FILE_FLAG_DELETE_ON_CLOSE Case FileOptions.Encrypted Case FileOptions.None op=0 Case FileOptions.RandomAccess op=FILE_FLAG_RANDOM_ACCESS Case FileOptions.SequentialScan op=FILE_FLAG_SEQUENTIAL_SCAN Case FileOptions.WriteThrough op=FILE_FLAG_WRITE_THROUGH End Select This.handle=CreateFile(path As PSTR,ac,sh,ByVal NULL,mo,op,0) If This.handle=INVALID_HANDLE_VALUE Then 'エラー処理 'Throw ArgumentException 'Throw IOException 'Throw System.IO.FileNotFoundException This.handle=0 Exit Sub End If filePath = path fileMode = mo fileAccess = ac fileShare = sh fileOptions = op End Sub Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare) FileStream(path,mode,access,share,FileOptions.None) End Sub Sub FileStream(path As String, mode As FileMode, access As FileAccess) FileStream(path,mode,access,FileShare.None,FileOptions.None) End Sub Sub FileStream(path As String, mode As FileMode) Dim access As FileAccess Select Case mode Case FileMode.Append access=FileAccess.Write Case FileMode.Create access=FileAccess.ReadWrite Case FileMode.CreateNew access=FileAccess.ReadWrite Case FileMode.Open access=FileAccess.ReadWrite Case FileMode.OpenOrCreate access=FileAccess.ReadWrite Case FileMode.Truncate access=FileAccess.Write End Select FileStream(path,mode,access,FileShare.None,FileOptions.None) End Sub Sub ~FileStream() This.Flush() This.Close() End Sub Public Override Function CanRead() As Boolean /* ファイルが読み込みに対応しているかを返す */ If fileAccess=GENERIC_READ/*FileAccess.Read*/ or fileAccess=GENERIC_READ or GENERIC_WRITE/*FileAccess.ReadWrite*/ Then Return True Else Return False End If End Function Override Function CanSeek() As Boolean /* ファイルがシークに対応しているかを返す */ Return True End Function Override Function CanTimeout() As Boolean /* ファイルがタイムアウトに対応しているかを返す */ Return False /*今のところ対応していないのでFalse*/ End Function Override Function CanWrite() As Boolean /* ファイルが書き込みに対応しているかを返す */ If fileAccess=GENERIC_WRITE/*FileAccess.Write*/ or fileAccess=GENERIC_READ or GENERIC_WRITE/*FileAccess.ReadWrite*/ Then Return True Else Return False End If End Function /*Handle*/ Function IsAsync() As Boolean /* ファイルが非同期操作に対応しているかを返す */ If fileOptions=FILE_FLAG_OVERLAPPED/*FileOptions.Asynchronous*/ Then Return True Else Return False End If End Function Override Function Length() As Int64 /* ファイルのサイズの取得 */ Dim s As LARGE_INTEGER s.LowPart=GetFileSize(This.handle,VarPtr(s.HighPart) As *DWord) memcpy(VarPtr(Length),VarPtr(s),SizeOf(LARGE_INTEGER)) End Function Function Name() As String /* 多分文字列をコピーして返す方がいいのと思うが。。。*/ Return filePath End Function Override Sub Position(value As Int64) /* ファイルポインタの位置の設定 */ Dim o As LARGE_INTEGER memcpy(VarPtr(o),VarPtr(value),SizeOf(LARGE_INTEGER)) If o.HighPart=0 And value<0 Then o.LowPart=-Abs(o.LowPart) As Long End If Dim ret As LARGE_INTEGER SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_CURRENT) End Sub Override Function Position() As Int64 /* ファイルポインタの位置の取得 */ Dim o As LARGE_INTEGER o.HighPart=0 o.LowPart=0 o.LowPart=SetFilePointer(This.handle,0,VarPtr(o.HighPart) As *DWord,FILE_CURRENT) memcpy(VarPtr(Position),VarPtr(o),SizeOf(LARGE_INTEGER)) End Function Override Sub ReadTimeout(value As Long) 'TODO End Sub Override Function ReadTimeout() As Long 'TODO End Function /* Safe〜Handle系の実装は要相談!! */ /* Function SafeFileHandle() As SafeFileHandle End Function*/ Override Sub WriteTimeout(value As Long) 'TODO End Sub Override Function WriteTimeout() As Long 'TODO End Function Public Override Function BeginRead(ByRef buffer[] As Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult 'TODO End Function Override Function BeginWrite(ByRef buffer[] As Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult 'TODO End Function Override Sub Close() CloseHandle(This.handle) End Sub /* CreateObjRef*/ /* Dispose*/ Override Sub EndRead(ByRef asyncResult As System.IAsyncResult) 'TODO End Sub Override Sub EndWrite(ByRef asyncResult As System.IAsyncResult) 'TODO End Sub /* Equals*/ Override Sub Flush() FlushFileBuffers(This.handle) End Sub /* Function GetAccessControl() As FileSecurity FileSecurityの実装がまだできてない。 End Function*/ Override Function GetHashCode() As Long Return ObjPtr(This) As Long End Function /* GetLifetimeService*/ /* Override Function GetType() As TypeInfo Return Super.GetType() End Function*/ /* InitializeLifetimeService*/ Sub Lock(position As Int64, length As Int64) Dim p As LARGE_INTEGER Dim l As LARGE_INTEGER memcpy(VarPtr(p),VarPtr(position),SizeOf(LARGE_INTEGER)) memcpy(VarPtr(l),VarPtr(length),SizeOf(LARGE_INTEGER)) LockFile(This.handle,p.LowPart,p.HighPart,l.LowPart,l.HighPart) End Sub Override Function Read(ByRef buffer[] As Byte, offset As Long, count As Long) As Long If offset Then SetFilePointer(This.handle,offset,NULL,FILE_CURRENT) End If ReadFile(This.handle,buffer,count,VarPtr(Read) As *DWord,ByVal NULL) End Function Override Function ReadByte() As Long Dim b As Byte Dim ret = Read(b, 0, 1) If ret <> 0 Then Return b As Long Else Return -1 End If End Function /* ReferenceEquals*/ Override Function Seek(offset As Int64, origin As SeekOrigin) As Long Dim o As LARGE_INTEGER memcpy(VarPtr(o),VarPtr(offset),SizeOf(LARGE_INTEGER)) If o.HighPart=0 And offset<0 Then o.LowPart=-o.LowPart End If Select Case origin Case SeekOrigin.Begin SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_BEGIN) Case SeekOrigin.Current SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_CURRENT) Case SeekOrigin.End SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_END) End Select End Function /* Sub SetAccessControl(fileSecurity As FileSecurity) FileSecurityの実装がまだできてない。 End Sub*/ Override Sub SetLength(value As Int64) Dim o As LARGE_INTEGER memcpy(VarPtr(o),VarPtr(value),SizeOf(LARGE_INTEGER)) If o.HighPart=0 And value<0 Then o.LowPart=-o.LowPart End If If Length()=>value Then SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_BEGIN) SetEndOfFile(This.handle) End If End Sub /* Synchronized*/ Override Function ToString() As String Return Name() End Function Sub Unlock(position As Int64, length As Int64) Dim p As LARGE_INTEGER Dim l As LARGE_INTEGER memcpy(VarPtr(p),VarPtr(position),SizeOf(LARGE_INTEGER)) memcpy(VarPtr(l),VarPtr(length),SizeOf(LARGE_INTEGER)) UnlockFile(This.handle,p.LowPart,p.HighPart,l.LowPart,l.HighPart) End Sub Override Sub Write(ByRef buffer[] As Byte, offset As Long, count As Long) If offset Then SetFilePointer(This.handle,offset,NULL,FILE_CURRENT) End If Dim ret As DWord WriteFile(This.handle,buffer,count,VarPtr(ret),ByVal NULL) End Sub Override Sub WriteByte(b As Byte) Write(b, 0, 1) End Sub Protected /*非同期ファイル操作に必須だがどうやって実装しようか検討中*/ Override Function CreateWaitHandle() As System.Threading.WaitHandle ' Return Nothing End Function /* Dispose Finalize MemberwiseClone*/ End Class End Namespace End Namespace