source: trunk/Include/Classes/System/IO/FileStream.ab@ 337

Last change on this file since 337 was 337, checked in by dai, 17 years ago

index.abを一つにまとめた。

File size: 11.1 KB
RevLine 
[271]1Namespace System
2Namespace IO
[256]3
[271]4
[260]5/* ほんとはmiscに入れるかかファイルを分けたほうがいいかもしれないが一先ず実装 */
[256]6Enum FileOptions
7 Asynchronous
8 DeleteOnClose
9 Encrypted
10 None
11 RandomAccess
12 SequentialScan
13 WriteThrough
14End Enum
15
[105]16Class FileStream
[256]17 Inherits Stream
18
19 handle As HANDLE
20
21 /*
[260]22 ファイルハンドルからこれらを取得できれば、これらは入らないが
[256]23 今のところは不明なので自前で実装するしかない
24 */
25 filePath As String
26 fileMode As DWord
27 fileAccess As DWord
28 fileShare As DWord
29 fileOptions As DWord
[336]30 fileReadOverlapped As OVERLAPPED
31 fileWriteOverlapped As OVERLAPPED
[256]32
33Public
[260]34 /* コンストラクタ.NETと同じように実装は難しい、一先ず動くものを実装したが変更が必要だと思う */
[256]35 Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare, options As FileOptions)
[260]36 Dim ac As DWord
37 Dim mo As DWord
38 Dim sh As DWord
39 Dim op As DWord
[256]40
41 Select Case access
42 Case FileAccess.Read
[260]43 ac=GENERIC_READ
[256]44 Case FileAccess.ReadWrite
[260]45 ac=GENERIC_READ or GENERIC_WRITE
[256]46 Case FileAccess.Write
[260]47 ac=GENERIC_WRITE
[256]48 End Select
49
50 Select Case share
51 Case FileShare.DeleteFile
[260]52 sh=FILE_SHARE_DELETE
[256]53 Case FileShare.None
[260]54 sh=0
[256]55 Case FileShare.Read
[260]56 sh=FILE_SHARE_READ
[256]57 Case FileShare.ReadWrite
[260]58 sh=FILE_SHARE_READ or FILE_SHARE_WRITE
59 Case FileShare.Write
60 sh=FILE_SHARE_WRITE
[256]61 End Select
62
63 Select Case mode
64 Case FileMode.Append
65 mo=OPEN_ALWAYS
66 Case FileMode.Create
67 mo=CREATE_ALWAYS
68 Case FileMode.CreateNew
69 mo=CREATE_NEW
70 Case FileMode.Open
71 mo=OPEN_EXISTING
72 Case FileMode.OpenOrCreate
73 mo=OPEN_ALWAYS
74 Case FileMode.Truncate
75 mo=TRUNCATE_EXISTING
76 End Select
77
78 Select Case options
[260]79 Case FileOptions.Asynchronous
80 op=FILE_FLAG_OVERLAPPED
[256]81 Case FileOptions.DeleteOnClose
[260]82 op=FILE_FLAG_DELETE_ON_CLOSE
[256]83 Case FileOptions.Encrypted
84 Case FileOptions.None
[260]85 op=0
[256]86 Case FileOptions.RandomAccess
[260]87 op=FILE_FLAG_RANDOM_ACCESS
[256]88 Case FileOptions.SequentialScan
[260]89 op=FILE_FLAG_SEQUENTIAL_SCAN
[256]90 Case FileOptions.WriteThrough
[260]91 op=FILE_FLAG_WRITE_THROUGH
[256]92 End Select
93
[289]94 This.handle=CreateFile(path As PSTR,ac,sh,ByVal NULL,mo,op,0)
[260]95 If This.handle=INVALID_HANDLE_VALUE Then
[256]96 'エラー処理
97 'Throw ArgumentException
98 'Throw IOException
99 'Throw System.IO.FileNotFoundException
[260]100 This.handle=0
[336]101 Beep(220,500)
[256]102 Exit Sub
103 End If
104
[336]105 This.filePath = path
106 This.fileMode = mo
107 This.fileAccess = ac
108 This.fileShare = sh
109 This.fileOptions = op
[256]110 End Sub
[260]111 Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare)
[336]112 This.FileStream(path,mode,access,share,FileOptions.None)
[260]113 End Sub
114 Sub FileStream(path As String, mode As FileMode, access As FileAccess)
[336]115 This.FileStream(path,mode,access,FileShare.None,FileOptions.None)
[260]116 End Sub
[256]117 Sub FileStream(path As String, mode As FileMode)
[260]118 Dim access As FileAccess
[256]119 Select Case mode
120 Case FileMode.Append
[260]121 access=FileAccess.Write
[256]122 Case FileMode.Create
[260]123 access=FileAccess.ReadWrite
[256]124 Case FileMode.CreateNew
[260]125 access=FileAccess.ReadWrite
[256]126 Case FileMode.Open
[260]127 access=FileAccess.ReadWrite
[256]128 Case FileMode.OpenOrCreate
[260]129 access=FileAccess.ReadWrite
[256]130 Case FileMode.Truncate
[260]131 access=FileAccess.Write
[256]132 End Select
[336]133 This.FileStream(path,mode,access,FileShare.None,FileOptions.None)
[256]134 End Sub
135
136 Sub ~FileStream()
137 This.Flush()
138 This.Close()
139 End Sub
140
141Public
142 Override Function CanRead() As Boolean
143 /* ファイルが読み込みに対応しているかを返す */
[336]144 If This.fileAccess And GENERIC_READ Then
[256]145 Return True
146 Else
147 Return False
148 End If
149 End Function
150
151 Override Function CanSeek() As Boolean
152 /* ファイルがシークに対応しているかを返す */
[336]153 If GetFileType(This.handle)=FILE_TYPE_DISK Then
154 Return True
155 Else
156 Return False
157 End If
[256]158 End Function
159
[336]160' Override Function CanTimeout() As Boolean
161' /* ファイルがタイムアウトに対応しているかを返す */
162' Return False /*今のところ対応していないのでFalse*/
163' End Function*/
[256]164
165 Override Function CanWrite() As Boolean
166 /* ファイルが書き込みに対応しているかを返す */
[336]167 If This.fileAccess And GENERIC_WRITE Then
[256]168 Return True
169 Else
170 Return False
171 End If
172 End Function
173
174 /*Handle*/
175
176 Function IsAsync() As Boolean
177 /* ファイルが非同期操作に対応しているかを返す */
[336]178 If This.fileOptions=FILE_FLAG_OVERLAPPED/*FileOptions.Asynchronous*/ Then
[256]179 Return True
180 Else
181 Return False
182 End If
183 End Function
184
185 Override Function Length() As Int64
[336]186 If This.CanSeek() Then
187 Dim length As LARGE_INTEGER
188 length.LowPart=GetFileSize(This.handle,VarPtr(length.HighPart) As *DWord)
189 Return MAKEQWORD(length.LowPart,length.HighPart)
190 End If
[256]191 End Function
192
193 Function Name() As String
[336]194 Return New String(This.filePath)
[256]195 End Function
196
197 Override Sub Position(value As Int64)
[336]198 If This.CanSeek() Then
199 If This.IsAsync() Then
200 fileReadOverlapped.Offset=LODWORD(value)
201 fileReadOverlapped.OffsetHigh=HIDWORD(value)
202 fileWriteOverlapped.OffsetHigh=LODWORD(value)
203 fileWriteOverlapped.OffsetHigh=HIDWORD(value)
204 Else
205 Dim position As LARGE_INTEGER
206 position.LowPart=LODWORD(value)
207 position.HighPart=HIDWORD(value)
208 SetFilePointer(This.handle,position.LowPart,VarPtr(position.HighPart) As *DWord,FILE_BEGIN)
209 End If
[256]210 End If
211 End Sub
212 Override Function Position() As Int64
[336]213 If This.CanSeek() Then
214 If This.IsAsync() Then
215 Return MAKEQWORD(fileReadOverlapped.Offset,fileReadOverlapped.OffsetHigh)
216 Else
217 Dim position As LARGE_INTEGER
218 ZeroMemory(VarPtr(position),SizeOf(LARGE_INTEGER))
219 position.LowPart=SetFilePointer(This.handle,position.LowPart,VarPtr(position.HighPart) As *DWord,FILE_CURRENT)
220 Return MAKEQWORD(position.LowPart,position.HighPart)
221 End If
222 End If
[256]223 End Function
224
[336]225/* Override Sub ReadTimeout(value As Long)
[256]226 'TODO
227 End Sub
228 Override Function ReadTimeout() As Long
229 'TODO
[336]230 End Function*/
[256]231
232 /* Safe~Handle系の実装は要相談!! */
233/* Function SafeFileHandle() As SafeFileHandle
234 End Function*/
235
236 Override Sub WriteTimeout(value As Long)
237 'TODO
238 End Sub
239 Override Function WriteTimeout() As Long
240 'TODO
241 End Function
242
243
244Public
[262]245 Override Function BeginRead(ByRef buffer[] As Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
[336]246 If This.IsAsync() Then
247 Else
248 Read(buffer,offset,count)
249 End If
[256]250 End Function
251
[262]252 Override Function BeginWrite(ByRef buffer[] As Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
[336]253 If This.IsAsync() Then
254 Else
255 Write(buffer,offset,count)
256 End If
[256]257 End Function
258
259 Override Sub Close()
260 CloseHandle(This.handle)
261 End Sub
262
263/* CreateObjRef*/
264/* Dispose*/
265
[262]266 Override Sub EndRead(ByRef asyncResult As System.IAsyncResult)
[256]267 'TODO
268 End Sub
269
[262]270 Override Sub EndWrite(ByRef asyncResult As System.IAsyncResult)
[256]271 'TODO
272 End Sub
273
274/* Equals*/
275
276 Override Sub Flush()
277 FlushFileBuffers(This.handle)
278 End Sub
279
280/* Function GetAccessControl() As FileSecurity
281 FileSecurityの実装がまだできてない。
282 End Function*/
283
284 Override Function GetHashCode() As Long
285 Return ObjPtr(This) As Long
286 End Function
287
288/* GetLifetimeService*/
289
290/* Override Function GetType() As TypeInfo
291 Return Super.GetType()
292 End Function*/
293
294/* InitializeLifetimeService*/
295
296 Sub Lock(position As Int64, length As Int64)
297 End Sub
298
[337]299 Override Function Read( buffer As *Byte, offset As Long, count As Long) As Long
[336]300 If This.CanRead() Then
301 Dim ret As DWord
302 If This.IsAsync() Then
303 ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),This.fileReadOverlapped)
304 While This.fileReadOverlapped.Internal=STATUS_PENDING
305 Wend
306 fileReadOverlapped.Offset+=LODWORD(ret)
307 fileReadOverlapped.OffsetHigh+=HIDWORD(ret)
308 fileWriteOverlapped.Offset+=LODWORD(ret)
309 fileWriteOverlapped.OffsetHigh+=HIDWORD(ret)
310 Return ret
311 Else
312 ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),ByVal NULL)
313 Return ret
314 End If
[256]315 End If
316 End Function
317
318/* ReferenceEquals*/
319
320 Override Function Seek(offset As Int64, origin As SeekOrigin) As Long
[336]321 If This.CanSeek() Then
322 If This.IsAsync() Then
323 Select Case origin
324 Case SeekOrigin.Begin
325 fileReadOverlapped.Offset=LODWORD(offset)
326 fileReadOverlapped.OffsetHigh=HIDWORD(offset)
327 fileWriteOverlapped.OffsetHigh=LODWORD(offset)
328 fileWriteOverlapped.OffsetHigh=HIDWORD(offset)
329 Case SeekOrigin.Current
330 fileReadOverlapped.Offset+=LODWORD(offset)
331 fileReadOverlapped.OffsetHigh+=HIDWORD(offset)
332 fileWriteOverlapped.Offset+=LODWORD(offset)
333 fileWriteOverlapped.OffsetHigh+=HIDWORD(offset)
334 Case SeekOrigin.End
335 fileReadOverlapped.Offset=LODWORD(This.Length()+offset)
336 fileReadOverlapped.OffsetHigh=HIDWORD(This.Length()+offset)
337 fileWriteOverlapped.Offset=LODWORD(This.Length()+offset)
338 fileWriteOverlapped.OffsetHigh=HIDWORD(This.Length()+offset)
339 End Select
340 Else
341 Dim seek As LARGE_INTEGER
342 seek.LowPart=LODWORD(offset)
343 seek.HighPart=HIDWORD(offset)
344 If seek.HighPart=0 And offset<0 Then seek.LowPart=-seek.LowPart
345 Select Case origin
346 Case SeekOrigin.Begin
347 Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_BEGIN)
348 Case SeekOrigin.Current
349 Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_CURRENT)
350 Case SeekOrigin.End
351 Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_CURRENT)
352 End Select
353 End If
[256]354 End If
355 End Function
356
357/* Sub SetAccessControl(fileSecurity As FileSecurity)
358 FileSecurityの実装がまだできてない。
359 End Sub*/
360
361 Override Sub SetLength(value As Int64)
[336]362 If This.CanWrite() and This.CanSeek() Then
363 If This.IsAsync() Then
364 Else
365 Dim current = This.Position()
366 This.Position(value)
367 SetEndOfFile(This.handle)
368 End If
[256]369 End If
370 End Sub
371
372/* Synchronized*/
373
374 Override Function ToString() As String
[336]375 Return This.Name()
[256]376 End Function
377
378 Sub Unlock(position As Int64, length As Int64)
379 End Sub
380
[337]381 Override Sub Write(buffer As *Byte, offset As Long, count As Long)
[336]382 If This.CanWrite() Then
383 Dim ret As DWord
384 If This.IsAsync() Then
385 WriteFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),This.fileWriteOverlapped)
386 While This.fileReadOverlapped.Internal=STATUS_PENDING
387 Wend
388 This.fileReadOverlapped.Offset+=LODWORD(ret)
389 This.fileReadOverlapped.OffsetHigh+=HIDWORD(ret)
390 This.fileWriteOverlapped.Offset+=LODWORD(ret)
391 This.fileWriteOverlapped.OffsetHigh+=HIDWORD(ret)
392 Else
393 WriteFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),ByVal NULL)
394 End If
[256]395 End If
396 End Sub
397
398Protected
[262]399 Override Function CreateWaitHandle() As System.Threading.WaitHandle
[336]400 '調査した限りでは、System.Threading.EventWaitHandleクラスをNewする模様。
401 '現状ではSystem.Threading.WaitHandleクラスをNewしてからHandleにて設定
402 Dim wh As System.Threading.WaitHandle
403 wh.Handle=CreateEvent(NULL,TRUE,FALSE,NULL)
404 Return wh
[256]405 End Function
406
407/* Dispose
408 Finalize
409 MemberwiseClone*/
[336]410Private
[105]411End Class
[271]412
413
414End Namespace
415End Namespace
Note: See TracBrowser for help on using the repository browser.