Changeset 391 for trunk/Include/Classes/System/IO/FileStream.ab
- Timestamp:
- Dec 7, 2007, 12:21:58 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Include/Classes/System/IO/FileStream.ab
r388 r391 4 4 /* ほんとはmiscに入れるかかファイルを分けたほうがいいかもしれないが一先ず実装 */ 5 5 Enum FileOptions 6 Asynchronous7 DeleteOnClose8 Encrypted9 None10 RandomAccess 11 SequentialScan 12 WriteThrough 6 None = 0 7 Asynchronous = FILE_FLAG_OVERLAPPED 8 DeleteOnClose = FILE_FLAG_DELETE_ON_CLOSE 9 Encrypted = FILE_ATTRIBUTE_ENCRYPTED 10 RandomAccess = FILE_FLAG_RANDOM_ACCESS 11 SequentialScan = FILE_FLAG_SEQUENTIAL_SCAN 12 WriteThrough = FILE_FLAG_WRITE_THROUGH 13 13 End Enum 14 14 … … 75 75 End Select 76 76 77 Select Case options 78 Case FileOptions.Asynchronous 79 op=FILE_FLAG_OVERLAPPED 80 Case FileOptions.DeleteOnClose 81 op=FILE_FLAG_DELETE_ON_CLOSE 82 Case FileOptions.Encrypted 83 Case FileOptions.None 84 op=0 85 Case FileOptions.RandomAccess 86 op=FILE_FLAG_RANDOM_ACCESS 87 Case FileOptions.SequentialScan 88 op=FILE_FLAG_SEQUENTIAL_SCAN 89 Case FileOptions.WriteThrough 90 op=FILE_FLAG_WRITE_THROUGH 91 End Select 92 93 This.handle=CreateFile(path As PSTR,ac,sh,ByVal NULL,mo,op,0) 77 op = options As DWord 78 If Not Environment.OSVersion.Platform = PlatformID.Win32NT Then 79 op And= Not FILE_FLAG_OVERLAPPED 80 End If 81 82 This.handle=CreateFile(ToTCStr(path),ac,sh,ByVal NULL,mo,op,0) 94 83 If This.handle=INVALID_HANDLE_VALUE Then 95 84 'エラー処理 … … 134 123 End Sub 135 124 Public 125 /*! 126 @brief ファイルが読み込みに対応しているかを返す 127 */ 136 128 Override Function CanRead() As Boolean 137 /* ファイルが読み込みに対応しているかを返す */138 129 If This.fileAccess And GENERIC_READ Then 139 130 Return True … … 143 134 End Function 144 135 136 /*! 137 @brief ファイルがシークに対応しているかを返す 138 */ 145 139 Override Function CanSeek() As Boolean 146 /* ファイルがシークに対応しているかを返す */147 140 If GetFileType(This.handle)=FILE_TYPE_DISK Then 148 141 Return True … … 157 150 ' End Function*/ 158 151 152 /*! 153 @brief ファイルが書き込みに対応しているかを返す 154 */ 159 155 Override Function CanWrite() As Boolean 160 /* ファイルが書き込みに対応しているかを返す */161 156 If This.fileAccess And GENERIC_WRITE Then 162 157 Return True … … 168 163 /*Handle*/ 169 164 165 /*! 166 @brief ファイルが非同期操作に対応しているかを返す 167 */ 170 168 Function IsAsync() As Boolean 171 /* ファイルが非同期操作に対応しているかを返す */172 169 If This.fileOptions And FILE_FLAG_OVERLAPPED /*FileOptions.Asynchronous*/ Then 173 170 Return True … … 178 175 179 176 Override Function Length() As Int64 177 disposedCheck() 180 178 If This.CanSeek() Then 181 Dim length As LARGE_INTEGER 182 length.LowPart=GetFileSize(This.handle,VarPtr(length.HighPart) As *DWord) 183 Return MAKEQWORD(length.LowPart,length.HighPart) As Int64 179 Dim length = VarPtr(Length) As *ULARGE_INTEGER 180 length->LowPart = GetFileSize(This.handle, VarPtr(length->HighPart)) 181 If LODWORD(Length) = INVALID_FILE_SIZE Then 182 Dim error = GetLastError() 183 If error <> NO_ERROR Then 184 ' Detail.ThrowWinIOException("FileStream.Read: Failed to read.", error) 185 End If 186 End If 187 188 If Length < 0 Then 189 Debug 'Throw OverflowException 190 End If 184 191 End If 185 192 End Function … … 190 197 191 198 Override Sub Position(value As Int64) 199 disposedCheck() 192 200 If This.CanSeek() Then 193 201 If This.IsAsync() Then … … 202 210 End Sub 203 211 Override Function Position() As Int64 212 disposedCheck() 204 213 If This.CanSeek() Then 205 214 If This.IsAsync() Then … … 266 275 267 276 Override Sub Flush() 268 FlushFileBuffers(This.handle) 277 disposedCheck() 278 Dim ret = FlushFileBuffers(This.handle) 279 If ret = FALSE Then 280 ' Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.") 281 End If 269 282 End Sub 270 283 … … 273 286 End Function*/ 274 287 275 Override Function GetHashCode() As Long276 Return ObjPtr(This) As Long277 End Function278 279 288 /* GetLifetimeService*/ 280 289 … … 286 295 287 296 Sub Lock(position As Int64, length As Int64) 297 disposedCheck() 288 298 If position < 0 Then 289 299 Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(position), "position") … … 296 306 297 307 Override Function Read( buffer As *Byte, offset As Long, count As Long) As Long 298 If This.CanRead() Then 299 Dim readBytes As DWord 300 If This.IsAsync() Then 301 Dim overlapped As OVERLAPPED 302 SetQWord(VarPtr(overlapped.Offset), offset) 303 Dim ret = ReadFile(This.handle, VarPtr(buffer[offset]), count, 0, overlapped) 308 disposedCheck() 309 If buffer = 0 Then 310 ' Throw ArgumentNullException("FileStream.Read: An argument is null value.", "buffer") 311 ElseIf Not This.CanRead() Then 312 ' Throw NotSupportedException("FileStream.Read: This stream is not readable.") 313 End If 314 315 Dim ret As BOOL 316 Dim readBytes As DWord 317 If This.IsAsync() Then 318 Dim overlapped As OVERLAPPED 319 SetQWord(VarPtr(overlapped.Offset), offset) 320 overlapped.hEvent = CreateEvent(0, TRUE, FALSE, 0) 321 If overlapped.hEvent = 0 Then 322 ' Throw OutOfMemoryException("FileStream.Read: Failed to create an event object.") 323 End If 324 Try 325 ret = ReadFile(This.handle, VarPtr(buffer[offset]), count, 0, overlapped) 304 326 If ret = FALSE Then 305 If GetLastError() = ERROR_IO_PENDING Then 306 GetOverlappedResult(This.handle, overlapped, readBytes, TRUE) 327 Dim error = GetLastError() 328 If error <> ERROR_IO_PENDING Then 329 ' Detail.ThrowWinIOException("FileStream.Read: Failed to read.", error) 307 330 End If 308 331 End If 332 ret = GetOverlappedResult(This.handle, overlapped, readBytes, TRUE) 333 If ret = FALSE Then 334 ' Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.") 335 End If 309 336 offset += Read 310 Else 311 ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(readBytes),ByVal NULL) 312 End If 313 Read = readBytes As Long 314 End If 315 End Function 316 317 /* ReferenceEquals*/ 318 319 Override Function Seek(offset As Int64, origin As SeekOrigin) As Long 337 Finally 338 CloseHandle(overlapped.hEvent) 339 End Try 340 Else 341 ret = ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(readBytes),ByVal NULL) 342 If ret = FALSE Then 343 ' Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.") 344 End If 345 End If 346 Read = readBytes As Long 347 End Function 348 349 /*! 350 @brief ストリームの現在位置を移動させる。 351 @param[in] offset originからの移動量 352 @param[in] origin 移動の基準位置 353 @return 移動後の新しい現在位置 354 @exception DisposedException 既にストリームが閉じられている場合 355 @exception ArgumentException 移動後の位置が負の位置(ファイル先頭より手前)になる場合 356 @exception IOException その他エラーが発生した場合 357 */ 358 Override Function Seek(offset As Int64, origin As SeekOrigin) As Int64 359 disposedCheck() 320 360 If This.CanSeek() Then 321 361 If This.IsAsync() Then … … 328 368 This.offset = This.Length + offset 329 369 End Select 370 Seek = This.offset As Int64 371 If Seek < 0 Then 372 ' Throw ArgumentException("FileStream.Seek: Cannot seek to negative offset.") 373 End If 330 374 Else 331 Dim seek As LARGE_INTEGER 332 seek.LowPart=LODWORD(offset) 333 seek.HighPart=HIDWORD(offset) 334 Select Case origin 335 Case SeekOrigin.Begin 336 Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_BEGIN) 337 Case SeekOrigin.Current 338 Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_CURRENT) 339 Case SeekOrigin.End 340 Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_CURRENT) 341 End Select 375 Dim seek = VarPtr(offset) As *ULARGE_INTEGER 376 Dim ret = SetFilePointer(This.handle, seek->LowPart, VarPtr(seek->HighPart), origin As DWord) 377 If ret = INVALID_SET_FILE_POINTER Then 378 Dim error = GetLastError() 379 If error = ERROR_NEGATIVE_SEEK Then 380 ' Throw ArgumentException("FileStream.Seek: Cannot seek to negative offset.") 381 ElseIf error <> NO_ERROR Then 382 ' Throw Detail.ThrowWinIOException("FileStream.Seek: Failed to seek.", error) 383 End If 384 End If 385 seek->LowPart = ret 386 Seek = offset 342 387 End If 343 388 End If … … 349 394 350 395 Override Sub SetLength(value As Int64) 396 disposedCheck() 351 397 If This.CanWrite() and This.CanSeek() Then 352 398 If This.IsAsync() Then … … 354 400 Dim current = This.Position() 355 401 This.Position(value) 356 SetEndOfFile(This.handle) 402 Dim ret = SetEndOfFile(This.handle) 403 If ret = FALSE Then 404 Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.") 405 End If 406 Position = current 357 407 End If 358 408 End If … … 366 416 367 417 Sub Unlock(position As Int64, length As Int64) 418 disposedCheck() 368 419 If position < 0 Then 369 420 Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(position), "position") … … 371 422 Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(length), "length") 372 423 End If 373 UnlockFile(handle, LODWORD(position As QWord), HIDWORD(position As QWord),424 Dim ret = UnlockFile(handle, LODWORD(position As QWord), HIDWORD(position As QWord), 374 425 LODWORD(length As QWord), HIDWORD(length As QWord)) 375 End Sub 376 426 If ret = FALSE Then 427 Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.") 428 End If 429 End Sub 377 430 378 431 Override Sub Write(buffer As *Byte, offset As Long, count As Long) 432 disposedCheck() 379 433 If This.CanWrite() Then 380 434 Dim writeBytes As DWord … … 382 436 Dim overlapped As OVERLAPPED 383 437 SetQWord(VarPtr(overlapped.Offset), offset) 438 overlapped.hEvent = CreateEvent(0, TRUE, FALSE, 0) 384 439 Dim ret = WriteFile(This.handle, VarPtr(buffer[offset]), count, 0, overlapped) 385 If ret = FALSE Then 386 If GetLastError() = ERROR_IO_PENDING Then 387 GetOverlappedResult(This.handle, overlapped, writeBytes, TRUE) 388 End If 440 If ret <> FALSE Or GetLastError() = ERROR_IO_PENDING Then 441 GetOverlappedResult(This.handle, overlapped, writeBytes, TRUE) 389 442 End If 390 443 offset += writeBytes 444 CloseHandle(overlapped.hEvent) 391 445 Else 392 446 WriteFile(This.handle, VarPtr(buffer[offset]), count, VarPtr(writeBytes), ByVal NULL) … … 394 448 End If 395 449 End Sub 396 397 450 398 451 Protected … … 405 458 End Function 406 459 407 /* Dispose408 Finalize409 MemberwiseClone*/410 460 Private 461 Sub disposedCheck() 462 If handle = 0 Then 463 ' Throw ObjectDisposedException("FileStream: This stream has closed.") 464 End If 465 End Sub 466 411 467 End Class 412 468
Note:
See TracChangeset
for help on using the changeset viewer.