Index: trunk/ab5.0/ablib/src/Classes/System/IO/Exception.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/Exception.ab	(revision 584)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/Exception.ab	(revision 605)
@@ -61,10 +61,23 @@
 	@brief	Windowsエラー値を基にIOExceptionを投げる。
 	@param[in] message	エラーメッセージ
+	@param[in] error	エラーコード
 	@author	Egtra
 	@date	2007/12/06
 	*/
 	Sub ThrowWinIOException(msg As String, error As DWord)
-		Throw New IOException(msg, HRESULT_FROM_WIN32(error))
+		Throw GetWinIOException(msg, error)
 	End Sub
+
+	/*!
+	@brief	Windowsエラー値を基にIOExceptionインスタンスを作成する。
+	@param[in] message	エラーメッセージ
+	@param[in] error	エラーコード
+	@return	作成されたIOExceptionインスタンス
+	@author	Egtra
+	@date	2008/08/21
+	*/
+	Function GetWinIOException(msg As String, error As DWord) As IOException
+		Return New IOException(msg, HRESULT_FROM_WIN32(error))
+	End Function
 
 	/*!
@@ -74,7 +87,19 @@
 	@date	2007/12/06
 	*/
-	Sub ThrowWinLastErrorIOException(msg As String)
-		Throw New IOException(msg, HRESULT_FROM_WIN32(GetLastError()))
+	Sub ThrowWinLastErrorIOException(msg = Nothing As String)
+		Throw GetWinLastErrorIOException(msg)
 	End Sub
+
+
+	/*!
+	@brief	GetLastError()の値を基にIOExceptionインスタンスを作成する。
+	@param[in] message	エラーメッセージ
+	@return	作成されたIOExceptionインスタンス
+	@author	Egtra
+	@date	2008/08/21
+	*/
+	Function GetWinLastErrorIOException(msg As String) As IOException
+		Return New IOException(msg, HRESULT_FROM_WIN32(GetLastError()))
+	End Function
 End Namespace
 
Index: trunk/ab5.0/ablib/src/Classes/System/IO/File.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/File.ab	(revision 584)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/File.ab	(revision 605)
@@ -1,56 +1,4 @@
 Namespace System
 Namespace IO
-
-/*
-@brief ファイルのアクセス方法を表す
-*/
-Enum FileAccess
-	Read      = GENERIC_READ
-	ReadWrite = GENERIC_READ Or GENERIC_WRITE
-	Write     = GENERIC_WRITE
-End Enum
-
-/*
-@brief ファイルの属性を表す
-*/
-Enum FileAttributes
-	Archive           = FILE_ATTRIBUTE_ARCHIVE
-	Compressed        = FILE_ATTRIBUTE_COMPRESSED
-	Device            = FILE_ATTRIBUTE_DEVICE
-	Directory         = FILE_ATTRIBUTE_DIRECTORY
-	Encrypted         = FILE_ATTRIBUTE_ENCRYPTED
-	Hidden            = FILE_ATTRIBUTE_HIDDEN
-	Normal            = FILE_ATTRIBUTE_NORMAL
-	NotContentIndexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
-	Offline           = FILE_ATTRIBUTE_OFFLINE
-	ReadOnly          = FILE_ATTRIBUTE_READONLY
-	ReparsePoint      = FILE_ATTRIBUTE_REPARSE_POINT
-	SparseFile        = FILE_ATTRIBUTE_SPARSE_FILE
-	System            = FILE_ATTRIBUTE_SYSTEM
-	Temporary         = FILE_ATTRIBUTE_TEMPORARY
-End Enum
-
-/*
-@brief ファイルの作成モードを表す
-*/
-Enum FileMode
-	Append       = OPEN_ALWAYS
-	Create       = CREATE_ALWAYS
-	CreateNew    = CREATE_NEW
-	Open         = OPEN_EXISTING
-	OpenOrCreate = OPEN_ALWAYS
-	Truncate     = TRUNCATE_EXISTING
-End Enum
-
-/*
-@brief ファイルの共有を表す
-*/
-Enum FileShare
-	None       = 0
-	Read       = FILE_SHARE_READ
-	Write      = FILE_SHARE_WRITE
-	ReadWrite  = FILE_SHARE_READ Or FILE_SHARE_WRITE
-	DeleteFile = FILE_SHARE_DELETE
-End Enum
 
 /*
Index: trunk/ab5.0/ablib/src/Classes/System/IO/FileStream.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/FileStream.ab	(revision 584)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/FileStream.ab	(revision 605)
@@ -1,85 +1,190 @@
+'Classes/System/IO/FileStream.ab
+
 Namespace System
 Namespace IO
 
-/* ほんとはmiscに入れるかかファイルを分けたほうがいいかもしれないが一先ず実装 */
-Enum FileOptions
-	None = 0
-	Asynchronous = FILE_FLAG_OVERLAPPED
-	DeleteOnClose = FILE_FLAG_DELETE_ON_CLOSE
-	Encrypted = FILE_ATTRIBUTE_ENCRYPTED
-	RandomAccess = FILE_FLAG_RANDOM_ACCESS
-	SequentialScan = FILE_FLAG_SEQUENTIAL_SCAN
-	WriteThrough = FILE_FLAG_WRITE_THROUGH
-End Enum
+/*
+(handle As IntPtr, access As FileAccess)
+(handle As IntPtr, access As FileAccess, ownsHandle As Boolean)
+(handle As IntPtr, access As FileAccess, ownsHandle As Boolean)
+(handle As IntPtr, access As FileAccess, ownsHandle As Boolean, isAsync As Boolean)
+(path As String, mode As FileMode)
+(path As String, mode As FileMode, access As FileAccess)
+(path As String, mode As FileMode, access As FileAccess, share As FileShare, useAsync As Boolean)
+(path As String, mode As FileMode, access As FileAccess, share As FileShare, options As FileOptions)
+(path As String, mode As FileMode, rights As FileSystemRights, share As FileShare, options As FileOptions)
+*/
 
 Class FileStream
 	Inherits Stream
-
-	handle As HANDLE
-
-	/*
-	ファイルハンドルからこれらを取得できれば、これらは入らないが
-	今のところは不明なので自前で実装するしかない
-	*/
-	filePath As String
-	fileMode As DWord
-	fileAccess As DWord
-	fileShare As DWord
-	fileOptions As DWord
-	ownsHandle As Boolean
-	
-	offset As QWord 'オーバーラップドIO用
-
-	Sub _Initialize(path As String, mode As FileMode, access As FileAccess, share As FileShare, options As FileOptions)
-		If ActiveBasic.IsNothing(path) Then
+Protected
+	Sub initialize(ac As DWord, owns As Boolean, isAsync As Boolean)
+		Imports ActiveBasic
+		ownsHandle = owns
+		If (ac And GENERIC_READ) = 0 Then
+			readFn = New Detail.Unreadable
+		End If
+		If (ac And GENERIC_WRITE) = 0 Then
+			writeFn = New Detail.Unwritable
+		End If
+		If GetFileType(handle) <> FILE_TYPE_DISK Then
+			seekFn = New Detail.Unseekable
+		End If
+		If isAsync Then
+			If IsNothing(seekFn) Then
+				seekFn = New Detail.OverlappedSeekable
+			End If
+			If IsNothing(readFn) Then
+				readFn = New Detail.OverlappedReadable
+			End If
+			If IsNothing(writeFn) Then
+				writeFn = New Detail.OverlappedWritable
+			End If
+		Else
+			If IsNothing(seekFn) Then
+				seekFn = New Detail.Seekable
+			End If
+			If IsNothing(readFn) Then
+				readFn = New Detail.Readable
+			End If
+			If IsNothing(writeFn) Then
+				writeFn = New Detail.Writable
+			End If
+		End If
+	End Sub
+
+	Sub openFile(path As String, mode As FileMode, rights As DWord, share As FileShare, ByRef options As FileOptions)
+		Imports ActiveBasic
+		If IsNothing(path) Then
 			Throw New ArgumentNullException("path")
 		ElseIf path.Length = 0 Then
-			Throw New ArgumentException
-		End If
-
-
-		Dim ac = access As DWord
+			Throw New ArgumentException("path.Length = 0")
+		End If
 		Dim sh = share As DWord
 		Dim mo = mode As DWord
 		Dim op = options As DWord
-'		If (Environment.OSVersion.Platform As DWord) <> (PlatformID.Win32NT As DWord) Then 'ToDo: なぜかアクセス違反になる
-			op And= Not FILE_FLAG_OVERLAPPED
-'		End If
-
-		This.handle=CreateFile(ToTCStr(path),ac,sh,ByVal NULL,mo,op,0)
-		If This.handle=INVALID_HANDLE_VALUE Then
+
+		If mode = FileMode.Append Then
+			mo = OPEN_ALWAYS
+			seekFn = New Detail.Unseekable
+		End If
+
+		Dim os = Environment.OSVersion
+		Dim platform = os.Platform As DWord
+		If platform = PlatformID.Win32Windows As DWord Or platform = PlatformID.Win32S As DWord Then
+			options = (op As DWord And Not FILE_FLAG_OVERLAPPED) As FileOptions
+		End If
+
+		handle = CreateFile(ToTCStr(path), rights, sh, ByVal NULL, mo, op, 0)
+		If handle = INVALID_HANDLE_VALUE Then
 		'エラー処理
 		'Throw ArgumentException
 		'Throw IOException
-		'Throw System.IO.FileNotFoundException 
-			This.handle=0
+		'Throw System.IO.FileNotFoundException
+			handle = 0
 			Detail.ThrowWinLastErrorIOException("Failed to open/create file.")
-			Exit Sub
-		End If
-
-		This.filePath = path
-		This.fileMode = mo
-		This.fileAccess = ac
-		This.fileShare = sh
-		This.fileOptions = op
-		This.offset = 0
-		This.ownsHandle = True
-
-		If FileMode.Append = This.fileMode Then
+		End If
+	
+		filePath = path
+
+		If mode = FileMode.Append Then
 			Seek(0, SeekOrigin.End)
 		End If
 	End Sub
 
+	Sub initWithOpen(path As String, mode As FileMode, access As FileAccess, share As FileShare, options As FileOptions)
+		openFile(path, mode, access As DWord, share, options)
+		initialize(access, True, UseOverlappled(options))
+	End Sub
+
+	Sub initWithOpen2(path As String, mode As FileMode, rights As DWord, share As FileShare, options As FileOptions)
+		openFile(path, mode, rights, share, options)
+		Dim ac = 0 As DWord
+		If (rights And GENERIC_READ) Or (rights And FILE_READ_DATA) Then
+			ac = (ac As DWord Or GENERIC_READ) As FileAccess
+		End If
+		If (rights And GENERIC_WRITE) Or (rights And FILE_WRITE_DATA) Then
+			ac = (ac As DWord Or GENERIC_WRITE) As FileAccess
+		End If
+		initialize(ac, True, UseOverlappled(options))
+	End Sub
+
+	Static Function UseOverlappled(options As FileOptions) As Boolean
+		Dim op = options As DWord
+		If op And FILE_FLAG_OVERLAPPED Then
+			UseOverlappled = True
+		Else
+			UseOverlappled = False
+		End If
+	End Function
+
+	Sub FileStream()
+	End Sub
 Public
-	/* コンストラクタ.NETと同じように実装は難しい、一先ず動くものを実装したが変更が必要だと思う */
+	/*!
+	@brief ファイルを開く。
+	@param[in] path ファイルパス
+	@param[in] mode 開き方
+	@param[in] rights 使用するアクセス権の指定
+	@param[in] share 共有方法
+	@param[in] option オプション
+	@date 2008/08/21
+	@auther Egtra
+	*/
+	Sub FileStream(path As String, mode As FileMode, rights As Security.AccessControl.FileSystemRights, share As FileShare, options As FileOptions)
+		initWithOpen2(path, mode, rights As DWord, share, options)
+	End Sub
+	/*!
+	@brief ファイルを開く。
+	@param[in] path ファイルパス
+	@param[in] mode 開き方
+	@param[in] access ファイルアクセスの指定
+	@param[in] share 共有方法
+	@param[in] option オプション
+	*/
 	Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare, options As FileOptions)
-		_Initialize( path, mode, access, share, options )
-	End Sub
+		initWithOpen(path, mode, access, share, options)
+	End Sub
+	/*!
+	@brief ファイルを開く。
+	@param[in] path ファイルパス
+	@param[in] mode 開き方
+	@param[in] access ファイルアクセスの指定
+	@param[in] share 共有方法
+	@param[in] useAsync 非同期にするならTrue
+	@date 2008/08/21
+	@auther Egtra
+	*/
+	Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare, useAsync As Boolean)
+		Dim options = FileOptions.None
+		If useAsync Then
+			options = FileOptions.Asynchronous
+		End If
+		initWithOpen(path, mode, access, share, options)
+	End Sub
+	/*!
+	@brief ファイルを開く。
+	@param[in] path ファイルパス
+	@param[in] mode 開き方
+	@param[in] access ファイルアクセスの指定
+	@param[in] share 共有方法
+	*/
 	Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare)
-		_Initialize(path,mode,access,share,FileOptions.None)
-	End Sub
+		initWithOpen(path,mode,access,share,FileOptions.None)
+	End Sub
+	/*!
+	@brief ファイルを開く。
+	@param[in] path ファイルパス
+	@param[in] mode 開き方
+	@param[in] access ファイルアクセスの指定
+	*/
 	Sub FileStream(path As String, mode As FileMode, access As FileAccess)
-		_Initialize(path,mode,access,FileShare.None,FileOptions.None)
-	End Sub
+		initWithOpen(path,mode,access,FileShare.None,FileOptions.None)
+	End Sub
+	/*!
+	@brief ファイルを開く。
+	@param[in] path ファイルパス
+	@param[in] mode 開き方
+	*/
 	Sub FileStream(path As String, mode As FileMode)
 		Dim access As FileAccess
@@ -98,17 +203,20 @@
 				access=FileAccess.Write
 		End Select
-		_Initialize(path,mode,access,FileShare.None,FileOptions.None)
-	End Sub
-	/*
+		initWithOpen(path,mode,access,FileShare.None,FileOptions.None)
+	End Sub
+	/*!
+	@brief 既存ハンドルを基にストリームを作る。
+	@param[in] h ハンドル
+	@param[in] access ファイルアクセスの指定
+	@param[in] owns 所有権を保持するかどうか（TrueならDispose時に基のハンドルも閉じる）
+	@param[in] isAsync 重複IOを使用するかどうか
 	@date 2008/02/26
 	@auther Egtra
-	'不要になったら削除すること
-	*/
-	Sub FileStream(h As HANDLE, access As FileAccess, owns As Boolean)
+	@todo SafeFileHandle版に置き換えること
+	*/
+	Sub FileStream(h As HANDLE, access As FileAccess, owns = True As Boolean, isAsync = False As Boolean)
 		handle = h
-		fileAccess = access As DWord
-		ownsHandle = owns
-	End Sub
-
+		initialize(access, owns, isAsync)
+	End Sub
 Public
 	/*!
@@ -116,9 +224,5 @@
 	*/
 	Override Function CanRead() As Boolean
-		If This.fileAccess And GENERIC_READ Then
-			Return True
-		Else
-			Return False
-		End If
+		Return readFn.CanRead
 	End Function
 
@@ -127,15 +231,6 @@
 	*/
 	Override Function CanSeek() As Boolean
-		If GetFileType(This.handle)=FILE_TYPE_DISK Then
-			Return True
-		Else
-			Return False
-		End If
-	End Function
-
-'	Override Function CanTimeout() As Boolean
-'		/* ファイルがタイムアウトに対応しているかを返す */
-'		Return False /*今のところ対応していないのでFalse*/
-'	End Function*/
+		Return seekFn.CanSeek
+	End Function
 
 	/*!
@@ -143,42 +238,17 @@
 	*/
 	Override Function CanWrite() As Boolean
-		If This.fileAccess And GENERIC_WRITE Then
-			Return True
-		Else
-			Return False
-		End If
-	End Function
-
+		Return writeFn.CanWrite
+	End Function
+
+	/*!
+	@brief	保持しているハンドルを返す
+	*/
 	Function Handle() As HANDLE
 		Return handle
 	End Function
 
-	/*!
-	@brief	ファイルが非同期操作に対応しているかを返す
-	*/
-	Function IsAsync() As Boolean
-		If This.fileOptions And FILE_FLAG_OVERLAPPED /*FileOptions.Asynchronous*/ Then
-			Return True
-		Else
-			Return False
-		End If
-	End Function
-
-	Override Function Length() As Int64
-		disposedCheck()
-		If This.CanSeek() Then
-			Dim length = VarPtr(Length) As *ULARGE_INTEGER
-			length->LowPart = GetFileSize(This.handle, VarPtr(length->HighPart))
-			If LODWORD(Length) = INVALID_FILE_SIZE Then
-				Dim error = GetLastError()
-				If error <> NO_ERROR Then
-'					Detail.ThrowWinIOException("FileStream.Read: Failed to read.", error)
-				End If
-			End If
-			
-			If Length < 0 Then
-				Debug 'Throw OverflowException
-			End If
-		End If
+	Override Function Length() As QWord
+		disposedCheck()
+		Length = seekFn.Length(This)
 	End Function
 
@@ -186,77 +256,45 @@
 		Return This.filePath
 	End Function
-	
-	Override Sub Position(value As Int64)
-		disposedCheck()
-		If This.CanSeek() Then
-			If This.IsAsync() Then
-				offset = value As QWord
-			Else
-				Dim position As LARGE_INTEGER
-				position.LowPart=LODWORD(value)
-				position.HighPart=HIDWORD(value)
-				SetFilePointer(This.handle,position.LowPart,VarPtr(position.HighPart) As *DWord,FILE_BEGIN)
-			End If
-		End If
-	End Sub
-	Override Function Position() As Int64
-		disposedCheck()
-		If This.CanSeek() Then
-			If This.IsAsync() Then
-				Return offset As Int64
-			Else
-				Dim position As LARGE_INTEGER
-				ZeroMemory(VarPtr(position),SizeOf(LARGE_INTEGER))
-				position.LowPart=SetFilePointer(This.handle,position.LowPart,VarPtr(position.HighPart) As *DWord,FILE_CURRENT)
-				Return MAKEQWORD(position.LowPart,position.HighPart) As Int64
-			End If
-		End If
-	End Function
-
-/*	Override Sub ReadTimeout(value As Long)
-		'TODO
-	End Sub
-	Override Function ReadTimeout() As Long
-		'TODO
-	End Function*/
-
+
+	Override Sub Position(value As QWord)
+		disposedCheck()
+		seekFn.Position(This, value)
+	End Sub
+	Override Function Position() As QWord
+		disposedCheck()
+		Position = seekFn.Position(This)
+	End Function
+
+Public
 	/* 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(buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
-		If This.IsAsync() Then
-		Else
-			Read(buffer,offset,count)
-		End If
+		disposedCheck()
+		If buffer = 0 Then
+			Throw New ArgumentNullException("FileStream.BeginRead", "buffer")
+		End If
+		BeginRead = readFn.BeginRead(This, buffer, offset, count, callback, state)
 	End Function
 
 	Override Function BeginWrite(buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
-		If This.IsAsync() Then
-		Else
-			Write(buffer,offset,count)
-		End If
-	End Function
-
-/*	CreateObjRef*/
-	
+		disposedCheck()
+		If buffer = 0 Then
+			Throw New ArgumentNullException("FileStream.BeginWrite", "buffer")
+		End If
+		BeginWrite = writeFn.BeginWrite(This, buffer, offset, count, callback, state)
+	End Function
+
 	Override Function EndRead(asyncResult As System.IAsyncResult) As Long
-		'TODO
+		disposedCheck()
+		EndRead = readFn.EndRead(This, asyncResult)
 	End Function
 
 	Override Sub EndWrite(asyncResult As System.IAsyncResult)
-		'TODO
-	End Sub
-
-/*	Equals*/
+		disposedCheck()
+		writeFn.EndWrite(This, asyncResult)
+	End Sub
 
 	Override Sub Flush()
@@ -264,5 +302,5 @@
 		Dim ret = FlushFileBuffers(This.handle)
 		If ret = FALSE Then
-'			Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
+			Detail.ThrowWinLastErrorIOException("FileStream.Flush: Failed to flush.")
 		End If
 	End Sub
@@ -272,21 +310,14 @@
 	End Function*/
 
-/*	GetLifetimeService*/
-
-/*	Override Function GetType() As TypeInfo
-		Return Super.GetType()
-	End Function*/
-
-/*	InitializeLifetimeService*/
-
-	Sub Lock(position As Int64, length As Int64)
+	Sub Lock(position As QWord, length As QWord)
 		disposedCheck()
 		If position < 0 Then
-			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(position), "position")
+			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.UInt64(position), "position")
 		ElseIf length < 0 Then
-			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(length), "length")
-		End If
-		LockFile(handle, LODWORD(position As QWord), HIDWORD(position As QWord),
-			LODWORD(length As QWord), HIDWORD(length As QWord))
+			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.UInt64(length), "length")
+		End If
+		If LockFile(handle, LODWORD(position), HIDWORD(position), LODWORD(length), HIDWORD(length)) = FALSE Then
+			Detail.ThrowWinLastErrorIOException("FileStream.Lock: Failed to lock.")
+		End If
 	End Sub
 
@@ -294,41 +325,7 @@
 		disposedCheck()
 		If buffer = 0 Then
-			Throw New ArgumentNullException("FileStream.Read: An argument is null value.", "buffer")
-		ElseIf Not This.CanRead() Then
-			Throw New NotSupportedException("FileStream.Read: This stream is not readable.")
-		End If
-
-		Dim ret As BOOL
-		Dim readBytes As DWord
-		If This.IsAsync() Then
-			Dim overlapped As OVERLAPPED
-			SetQWord(VarPtr(overlapped.Offset), offset)
-			overlapped.hEvent = CreateEvent(0, TRUE, FALSE, 0)
-			If overlapped.hEvent = 0 Then
-				Throw New OutOfMemoryException("FileStream.Read: Failed to create an event object.")
-			End If
-			Try
-				ret = ReadFile(This.handle, VarPtr(buffer[offset]), count, 0, overlapped)
-				If ret = FALSE Then
-					Dim error = GetLastError()
-					If error <> ERROR_IO_PENDING Then
-						Detail.ThrowWinIOException("FileStream.Read: Failed to read.", error)
-					End If
-				End If
-				ret = GetOverlappedResult(This.handle, overlapped, readBytes, TRUE)
-				If ret = FALSE Then
-					Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
-				End If
-				offset += Read
-			Finally
-				CloseHandle(overlapped.hEvent)
-			End Try
-		Else
-			ret = ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(readBytes),ByVal NULL)
-			If ret = FALSE Then
-				Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
-			End If
-		End If
-		Read = readBytes As Long
+			Throw New ArgumentNullException("FileStream.Read", "buffer")
+		End If
+		Read = readFn.Read(This, buffer, offset, count)
 	End Function
 
@@ -344,33 +341,5 @@
 	Override Function Seek(offset As Int64, origin As SeekOrigin) As Int64
 		disposedCheck()
-		If This.CanSeek() Then
-			If This.IsAsync() Then
-				Select Case origin
-					Case SeekOrigin.Begin
-						This.offset = offset
-					Case SeekOrigin.Current
-						This.offset += offset
-					Case SeekOrigin.End
-						This.offset = This.Length + offset
-				End Select
-				Seek = This.offset As Int64
-				If Seek < 0 Then
-'					Throw ArgumentException("FileStream.Seek: Cannot seek to negative offset.")
-				End If
-			Else
-				Dim seek = VarPtr(offset) As *ULARGE_INTEGER
-				Dim ret = SetFilePointer(This.handle, seek->LowPart, VarPtr(seek->HighPart), origin As DWord)
-				If ret = INVALID_SET_FILE_POINTER Then
-					Dim error = GetLastError()
-					If error = ERROR_NEGATIVE_SEEK Then
-'						Throw ArgumentException("FileStream.Seek: Cannot seek to negative offset.")
-					ElseIf error <> NO_ERROR Then
-'						Throw Detail.ThrowWinIOException("FileStream.Seek: Failed to seek.", error)
-					End If
-				End If
-				seek->LowPart = ret
-				Seek = offset
-			End If
-		End If
+		Seek = seekFn.Seek(This, offset, origin)
 	End Function
 
@@ -379,21 +348,8 @@
 	End Sub*/
 
-	Override Sub SetLength(value As Int64)
-		disposedCheck()
-		If This.CanWrite() and This.CanSeek() Then
-			If This.IsAsync() Then
-			Else
-				Dim current = This.Position()
-				This.Position(value)
-				Dim ret = SetEndOfFile(This.handle)
-				If ret = FALSE Then
-					Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
-				End If
-				Position = current
-			End If
-		End If
-	End Sub
-
-/*	Synchronized*/
+	Override Sub SetLength(value As QWord)
+		disposedCheck()
+		seekFn.SetLength(This, value)
+	End Sub
 
 	Override Function ToString() As String
@@ -401,15 +357,9 @@
 	End Function
 
-	Sub Unlock(position As Int64, length As Int64)
-		disposedCheck()
-		If position < 0 Then
-			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(position), "position")
-		ElseIf length < 0 Then
-			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(length), "length")
-		End If
-		Dim ret = UnlockFile(handle, LODWORD(position As QWord), HIDWORD(position As QWord),
-			LODWORD(length As QWord), HIDWORD(length As QWord))
+	Sub Unlock(position As QWord, length As QWord)
+		disposedCheck()
+		Dim ret = UnlockFile(handle, LODWORD(position), HIDWORD(position), LODWORD(length), HIDWORD(length))
 		If ret = FALSE Then
-			Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
+			Detail.ThrowWinLastErrorIOException("FileStream.Unlock failed")
 		End If
 	End Sub
@@ -417,20 +367,8 @@
 	Override Sub Write(buffer As *Byte, offset As Long, count As Long)
 		disposedCheck()
-		If This.CanWrite() Then
-			Dim writeBytes As DWord
-			If This.IsAsync() Then
-				Dim overlapped As OVERLAPPED
-				SetQWord(VarPtr(overlapped.Offset), offset)
-				overlapped.hEvent = CreateEvent(0, TRUE, FALSE, 0)
-				Dim ret = WriteFile(This.handle, VarPtr(buffer[offset]), count, 0, overlapped)
-				If ret <> FALSE Or GetLastError() = ERROR_IO_PENDING Then
-					GetOverlappedResult(This.handle, overlapped, writeBytes, TRUE)
-				End If
-				offset += writeBytes
-				CloseHandle(overlapped.hEvent)
-			Else
-				WriteFile(This.handle, VarPtr(buffer[offset]), count, VarPtr(writeBytes), ByVal NULL)
-			End If
-		End If
+		If buffer = 0 Then
+			Throw New ArgumentNullException("FileStream.Write", "buffer")
+		End If
+		writeFn.Write(This, buffer, offset, count)
 	End Sub
 
@@ -438,22 +376,22 @@
 	Override Sub Dispose(disposing As Boolean)
 		If handle <> 0 Then
-			Flush()
 			CloseHandle(InterlockedExchangePointer(ByVal VarPtr(handle), NULL))
 		End If
 	End Sub
 
-	Override Function CreateWaitHandle() As System.Threading.WaitHandle
-		Return New System.Threading.AutoResetEvent(False)
-	End Function
-
-Private
 	Sub disposedCheck()
 		If handle = 0 Then
-'			Throw ObjectDisposedException("FileStream: This stream has closed.")
-		End If
-	End Sub
-
+			Throw New ObjectDisposedException("FileStream: This stream has already closed.")
+		End If
+	End Sub
+
+Private
+	handle As HANDLE
+	seekFn As Detail.SeekFunctions
+	readFn As Detail.ReadFunctions
+	writeFn As Detail.WriteFunctions
+	filePath As String
+	ownsHandle As Boolean
 End Class
-
 
 End Namespace
Index: trunk/ab5.0/ablib/src/Classes/System/IO/FileStreamImpl.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/FileStreamImpl.ab	(revision 605)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/FileStreamImpl.ab	(revision 605)
@@ -0,0 +1,668 @@
+'Classes/System/IO/FileStreamImpl.ab
+
+Namespace System
+Namespace IO
+Namespace Detail
+
+Sub ThrowIfFilePointerFunctionFailed(dwLow As DWord)
+	If dwLow = INVALID_FILE_SIZE Then
+		Dim error = GetLastError()
+		If error <> NO_ERROR Then
+			Detail.ThrowWinIOException("FileStream: Failed to position or file size function.", error)
+		End If
+	End If
+End Sub
+
+/*!
+@brief シーク系関数の集合
+@date 2008/08/21
+@auther Egtra
+*/
+Class SeekFunctions
+Public
+	Abstract Function CanSeek() As Boolean
+	Abstract Function Seek(s As FileStream, offset As Int64, origin As SeekOrigin) As Int64
+	Abstract Sub Position(s As FileStream, value As QWord)
+	Abstract Function Position(s As FileStream) As QWord
+	Abstract Function Length(s As FileStream) As QWord
+	Abstract Sub SetLength(s As FileStream, value As QWord)
+End Class
+
+/*!
+@brief シークできない実装
+@date 2008/08/21
+@auther Egtra
+*/
+Class Unseekable
+	Inherits SeekFunctions
+Public
+	Override Function CanSeek() As Boolean
+		Return False
+	End Function
+	Override Function Seek(s As FileStream, offset As Int64, origin As SeekOrigin) As Int64
+		Throw New NotSupportedException("FileStream.Seek")
+	End Function
+	Override Sub Position(s As FileStream, vvalue As QWord)
+		Throw New NotSupportedException("FileStream.Position")
+	End Sub
+	Override Function Position(s As FileStream) As QWord
+		Throw New NotSupportedException("FileStream.Position")
+	End Function
+	Override Function Length(s As FileStream) As QWord
+		Throw New NotSupportedException("FileStream.Length")
+	End Function
+	Override Sub SetLength(s As FileStream, value As QWord)
+		Throw New NotSupportedException("FileStream.SetLength")
+	End Sub
+End Class
+
+/*!
+@brief シークできる実装
+@date 2008/08/21
+@auther Egtra
+*/
+Class Seekable
+	Inherits SeekFunctions
+Public
+	Override Function CanSeek() As Boolean
+		Return True
+	End Function
+	Override Function Seek(s As FileStream, offset As Int64, origin As SeekOrigin) As Int64
+		Dim seek = VarPtr(offset) As *LARGE_INTEGER
+		Dim ret = SetFilePointer(s.Handle, seek->LowPart As Long, VarPtr(seek->HighPart), origin As DWord)
+		If ret = INVALID_SET_FILE_POINTER Then
+			Dim error = GetLastError()
+			If error = ERROR_NEGATIVE_SEEK Then
+				Throw New ArgumentException("FileStream.Seek: Cannot seek to negative offset.")
+			ElseIf error <> NO_ERROR Then
+				Detail.ThrowWinIOException("FileStream.Seek: Failed to seek.", error)
+			End If
+		End If
+		seek->LowPart = ret
+		Seek = offset
+	End Function
+	Override Sub Position(s As FileStream, value As QWord)
+		Dim position = VarPtr(value) As *LARGE_INTEGER
+		With position[0]
+			Dim ret = SetFilePointer(s.Handle, .LowPart As Long, VarPtr(.HighPart), FILE_BEGIN)
+			ThrowIfFilePointerFunctionFailed(ret)
+		End With
+	End Sub
+	Override Function Position(s As FileStream) As QWord
+		Dim position = VarPtr(Position) As *LARGE_INTEGER
+		With position[0]
+			.LowPart = SetFilePointer(s.Handle, .LowPart As Long, VarPtr(.HighPart), FILE_CURRENT)
+			ThrowIfFilePointerFunctionFailed(.LowPart)
+		End With
+	End Function
+	Override Function Length(s As FileStream) As QWord
+		Dim length = VarPtr(Length) As *ULARGE_INTEGER
+		length->LowPart = GetFileSize(s.Handle, VarPtr(length->HighPart))
+		ThrowIfFilePointerFunctionFailed(length->LowPart)
+	End Function
+	Override Sub SetLength(s As FileStream, value As QWord)
+		If s.CanWrite() Then
+			Dim current = s.Position()
+			Position(s, value)
+			Dim ret = SetEndOfFile(s.Handle)
+			If ret = FALSE Then
+				Detail.ThrowWinLastErrorIOException("FileStream.SetLength failed")
+			End If
+			Position(s, current)
+		End If
+	End Sub
+End Class
+
+/*!
+@brief シークできる実装（重複IO用）
+@date 2008/08/21
+@auther Egtra
+*/
+Class OverlappedSeekable
+	Inherits Seekable
+Public
+	Override Function Seek(s As FileStream, offset As Int64, origin As SeekOrigin) As Int64
+		Seek = Super.Seek(s, offset, origin)
+		offset = Position(s)
+	End Function
+	Override Sub Position(s As FileStream, value As QWord)
+		Super.Position(s, value)
+		offset = value
+	End Sub
+	Override Function Position(s As FileStream) As QWord
+		Position = offset
+	End Function
+Private
+	offset As QWord
+End Class
+
+'---------------------------------------
+
+/*!
+@brief 読み取り関数の集合
+@date 2008/08/21
+@auther Egtra
+*/
+Class ReadFunctions
+Public
+	Abstract Function CanRead() As Boolean
+	Abstract Function Read(s As FileStream, buffer As *Byte, offset As Long, count As Long) As Long
+	Abstract Function BeginRead(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+	Abstract Function EndRead(s As FileStream, asyncResult As System.IAsyncResult) As Long
+End Class
+
+/*!
+@brief 読み取りできない実装
+@date 2008/08/21
+@auther Egtra
+*/
+Class Unreadable
+	Inherits ReadFunctions
+Public
+	Override Function CanRead() As Boolean
+		Return False
+	End Function
+
+	Override Function Read(s As FileStream, buffer As *Byte, offset As Long, count As Long) As Long
+		Throw New NotSupportedException("FileStream.Read")
+	End Function
+
+	Override Function BeginRead(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+		Throw New NotSupportedException("FileStream.BeginRead")
+	End Function
+
+	Override Function EndRead(s As FileStream, asyncResult As System.IAsyncResult) As Long
+		Throw New NotSupportedException("FileStream.EndRead")
+	End Function
+End Class
+
+/*!
+@brief 読み取りできる実装
+@date 2008/08/21
+@auther Egtra
+*/
+Class Readable
+	Inherits ReadFunctions
+Public
+	Override Function CanRead() As Boolean
+		Return True
+	End Function
+	Override Function Read(s As FileStream, buffer As *Byte, offset As Long, count As Long) As Long
+		Dim readBytes As DWord
+		Dim ret = ReadFile(s.Handle, VarPtr(buffer[offset]), count As DWord, VarPtr(readBytes), ByVal NULL)
+		If ret = FALSE Then
+			Detail.ThrowWinLastErrorIOException("FileStream.Read: Failed to read.")
+		End If
+		Read = readBytes As Long
+	End Function
+
+	Override Function BeginRead(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+		BeginRead = ThreadPoolIo(ToMBStr("ReadFile"), s, buffer, offset, count, callback, state)
+	End Function
+
+	Override Function EndRead(s As FileStream, asyncResult As System.IAsyncResult) As Long
+		Dim ar = asyncResult As Detail.IAsyncStreamResult
+		EndRead = ar.WaitAndGetResult
+	End Function
+End Class
+
+/*!
+@brief 読み取りできる実装（重複IO用）
+@date 2008/08/21
+@auther Egtra
+*/
+Class OverlappedReadable
+	Inherits Readable
+Public
+	Override Function Read(s As FileStream, buffer As *Byte, offset As Long, count As Long) As Long
+		Read = EndRead(s, BeginRead(s, buffer, offset, count, Nothing, Nothing))
+	End Function
+
+	Override Function BeginRead(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+		BeginRead = BeginOverlappedIo(ToMBStr("ReadFile"), s, buffer, offset, count, callback, state)
+		If s.CanSeek Then
+			s.Seek(count, SeekOrigin.Current)
+		End If
+	End Function
+End Class
+
+'---------------------------------------
+
+/*!
+@brief 書き込み関数の集合
+@date 2008/08/21
+@auther Egtra
+*/
+Class WriteFunctions
+Public
+	Abstract Function CanWrite() As Boolean
+	Abstract Sub Write(s As FileStream, buffer As *Byte, offset As Long, count As Long)
+	Abstract Function BeginWrite(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+	Abstract Sub EndWrite(s As FileStream, asyncResult As System.IAsyncResult)
+End Class
+
+/*!
+@brief 書き込みできない実装
+@date 2008/08/21
+@auther Egtra
+*/
+Class Unwritable
+	Inherits WriteFunctions
+Public
+	Override Function CanWrite() As Boolean
+		Return False
+	End Function
+
+	Override Sub Write(s As FileStream, buffer As *Byte, offset As Long, count As Long)
+		Throw New NotSupportedException("FileStream.Write")
+	End Sub
+
+	Override Function BeginWrite(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+		Throw New NotSupportedException("FileStream.BeginWrite")
+	End Function
+
+	Override Sub EndWrite(s As FileStream, asyncResult As System.IAsyncResult)
+		Throw New NotSupportedException("FileStream.EndWrite")
+	End Sub
+End Class
+
+/*!
+@brief 書き込みできる実装
+@date 2008/08/21
+@auther Egtra
+*/
+Class Writable
+	Inherits WriteFunctions
+Public
+	Override Function CanWrite() As Boolean
+		Return True
+	End Function
+
+	Override Sub Write(s As FileStream, buffer As *Byte, offset As Long, count As Long)
+		Dim readBytes As DWord
+		Dim ret = WriteFile(s.Handle, VarPtr(buffer[offset]), count As DWord, VarPtr(readBytes), ByVal NULL)
+		If ret = FALSE Then
+			Detail.ThrowWinLastErrorIOException("FileStream.Write: Failed to write.")
+		End If
+	End Sub
+
+	Override Function BeginWrite(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+		BeginWrite = ThreadPoolIo(ToMBStr("WriteFile"), s, buffer, offset, count, callback, state)
+	End Function
+
+	Override Sub EndWrite(s As FileStream, asyncResult As System.IAsyncResult)
+		Dim ar = asyncResult As Detail.IAsyncStreamResult
+		ar.WaitAndGetResult()
+	End Sub
+End Class
+
+/*!
+@brief 書き込みできる実装（重複IO用）
+@date 2008/08/21
+@auther Egtra
+*/
+Class OverlappedWritable
+	Inherits Writable
+Public
+	Override Sub Write(s As FileStream, buffer As *Byte, offset As Long, count As Long)
+		EndWrite(s, BeginWrite(s, buffer, offset, count, Nothing, Nothing))
+	End Sub
+
+	Override Function BeginWrite(s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+		BeginWrite = BeginOverlappedIo(ToMBStr("WriteFile"), s, buffer, offset, count, callback, state)
+		If s.CanSeek Then
+			s.Seek(count, SeekOrigin.Current)
+		End If
+	End Function
+End Class
+
+'---------------------------------------
+
+/*!
+@brief 重複IO実行開始
+@param[in] fn "ReadFile"か"WriteFile"または引数に互換性のあるkernel32の関数名
+@param[in] s 対象のストリーム
+@param[in,out] buffer 入出力先
+@param[in] offset buffer内で入出力を開始する位置
+@param[in] count 読み書きするバイト数
+@param[in] callback 完了したときに呼ばれるデリゲート
+@param[in] state IAsyncResultへの追加引数
+@return EndRead/Writeへの引き換えとなるIAsyncResult
+@date 2008/08/21
+@auther Egtra
+*/
+Function BeginOverlappedIo(fn As PCSTR, s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As Detail.AsyncStreamResult
+	Dim ioFile = GetProcAddress(GetModuleHandle("kernel32.dll"), fn) As Detail.PIOFile
+	BeginOverlappedIo = New Detail.AsyncStreamResult(s.Handle, state)
+	Dim pov = BeginOverlappedIo.PtrToOverlapped
+	Dim position = s.Position
+	pov->Offset = LODWORD(position)
+	pov->OffsetHigh = HIDWORD(position)
+	position += count
+	If ioFile(s.Handle, buffer + offset, count, 0, pov) Then
+		BeginOverlappedIo.SetCompletedSynchronously()
+	Else
+		Dim lastError = GetLastError()
+		If lastError = ERROR_IO_PENDING Then
+			If Not ActiveBasic.IsNothing(callback) Then
+				Dim d = New Detail.CallbackData
+				d.Callback = callback
+				d.Result = BeginOverlappedIo
+				Threading.ThreadPool.RegisterWaitForSingleObject(BeginOverlappedIo.AsyncWaitHandle, AddressOf(CallAsyncCallbackB), d)
+			End If
+			Exit Function
+		ElseIf lastError = ERROR_HANDLE_EOF Then
+			BeginOverlappedIo.SetCompletedSynchronously()
+			BeginOverlappedIo.Handle = 0
+			BeginOverlappedIo.Result = 0
+		Else
+			Detail.ThrowWinIOException("AsyncFileStream", lastError)
+		End If
+	End If
+	If Not ActiveBasic.IsNothing(callback) Then
+		Dim d = New Detail.CallbackData
+		d.Callback = callback
+		d.Result = BeginOverlappedIo
+		Threading.ThreadPool.QueueUserWorkItem(AddressOf(CallAsyncCallback), d)
+	End If
+End Function
+
+/*!
+@brief BeginOverlappedIoのコールバック補助
+@return EndRead/Writeへの引き換えとなるIAsyncResult
+@date 2008/08/21
+@auther Egtra
+*/
+Sub CallAsyncCallbackB(o As Object, b As Boolean)
+	CallAsyncCallback(o)
+End Sub
+
+/*!
+@brief BeginOverlappedIoのコールバック補助
+@return EndRead/Writeへの引き換えとなるIAsyncResult
+@date 2008/08/21
+@auther Egtra
+*/
+Sub CallAsyncCallback(o As Object)
+	Dim d = o As Detail.CallbackData
+	Dim c = d.Callback
+	c(d.Result)
+End Sub
+
+/*!
+@brief Stream用IAsyncResult拡張
+@date 2008/08/21
+@auther Egtra
+*/
+Interface IAsyncStreamResult
+	Inherits IAsyncResult
+	/*!
+	@brief 入出力完了まで待機する
+	@return 読み書きしたバイト数
+	*/
+	Function WaitAndGetResult() As DWord
+End Interface
+
+/*!
+@brief IAsyncStreamResult実装用基底クラス
+@date 2008/08/21
+@auther Egtra
+2つの派生クラス、AsyncStreamResultとThreadPoolIoResultの共通部分
+*/
+Class AsyncStreamResultImplBase
+	Implements IAsyncStreamResult
+Protected
+	Sub AsyncStreamResultImplBase(state As Object)
+		Imports System.Threading
+		wait = New EventWaitHandle(False, EventResetMode.ManualReset)
+		s = state
+	End Sub
+Public
+	Virtual Function AsyncWaitHandle() As Threading.WaitHandle
+		AsyncWaitHandle = wait
+	End Function
+
+	Virtual Function CompletedSynchronously() As Boolean
+	End Function
+
+	Virtual Function IsCompleted() As Boolean
+		IsCompleted = AsyncWaitHandle.WaitOne(0)
+	End Function
+
+	Virtual Function AsyncState() As Object
+		AsyncState = s
+	End Function
+
+	Virtual Function WaitAndGetResult() As DWord
+	End Function
+
+	Function AsyncEventWaitHandle() As Threading.EventWaitHandle
+		AsyncEventWaitHandle = wait
+	End Function
+Private
+	wait As Threading.EventWaitHandle
+	s As Object
+End Class
+
+/*!
+@brief 重複IO用IAsyncStreamResult実装
+@date 2008/08/21
+@auther Egtra
+*/
+Class AsyncStreamResult
+	Inherits AsyncStreamResultImplBase
+Public
+	Sub AsyncStreamResult(handle As HANDLE, state As Object)
+		AsyncStreamResultImplBase(state)
+		h = handle
+		cs = False
+		overlapped.hEvent = AsyncWaitHandle.Handle
+	End Sub
+
+	Override Function CompletedSynchronously() As Boolean
+		CompletedSynchronously = cs
+	End Function
+
+	Sub SetCompletedSynchronously()
+		cs = True
+		wait.Set()
+	End Sub
+
+	Override Function WaitAndGetResult() As DWord
+		If h <> 0 Then
+			If GetOverlappedResult(h, overlapped, result, TRUE) = FALSE Then
+				Detail.ThrowWinLastErrorIOException("FileStream.EndRead/Write")
+			End If
+			h = 0
+		End If
+		WaitAndGetResult = result
+	End Function
+
+	Function PtrToOverlapped() As *OVERLAPPED
+		PtrToOverlapped = VarPtr(overlapped)
+	End Function
+
+	Sub Handle(handle As HANDLE)
+		h = handle
+	End Sub
+
+	'同期IO用
+	Sub Result(res As DWord)
+		result = res
+	End Sub
+Private
+	overlapped As OVERLAPPED
+	h As HANDLE
+	result As DWord
+	cs As Boolean
+End Class
+
+/*!
+@brief ThreadPoolIo用IAsyncStreamResult実装
+@date 2008/08/21
+@auther Egtra
+ThreadPoolIo関数も参照
+*/
+Class ThreadPoolIoResult
+	Inherits AsyncStreamResultImplBase
+Public
+	Sub ThreadPoolIoResult(state As Object)
+		AsyncStreamResultImplBase(state)
+	End Sub
+
+	Override Function CompletedSynchronously() As Boolean
+		CompletedSynchronously = False
+	End Function
+
+	Override Function WaitAndGetResult() As DWord
+		AsyncWaitHandle.WaitOne()
+		If Not ActiveBasic.IsNothing(ex) Then
+			Throw ex
+		End If
+		WaitAndGetResult = Result
+	End Function
+
+	Sub SetException(e As Exception)
+		ex = e
+	End Sub
+
+	Result As DWord
+Private
+	ex As Exception
+End Class
+
+/*!
+@brief Stream用同期IAsyncStreamResult実装
+@date 2008/08/21
+@auther Egtra
+StreamでのBeginRead/Writeの実装は、常にBegin内部で同期的に処理するというもの。これはそれ用の実装。
+*/
+Class SyncStreamResultImpl
+	Implements IAsyncStreamResult
+Public
+	Sub SyncStreamResultImpl(result As DWord, state As Object)
+		Imports System.Threading
+		wait = New EventWaitHandle(False, EventResetMode.ManualReset)
+		s = state
+	End Sub
+
+	Virtual Function AsyncWaitHandle() As Threading.WaitHandle
+		Imports System.Threading
+		If ActiveBasic.IsNothing(wait) Then
+			wait = New EventWaitHandle(True, EventResetMode.ManualReset)
+		End If
+		AsyncWaitHandle = wait
+	End Function
+
+	Virtual Function CompletedSynchronously() As Boolean
+		CompletedSynchronously = True
+	End Function
+
+	Virtual Function IsCompleted() As Boolean
+		IsCompleted = True
+	End Function
+
+	Virtual Function AsyncState() As Object
+		AsyncState = s
+	End Function
+
+	Virtual Function WaitAndGetResult() As DWord
+		WaitAndGetResult = res
+	End Function
+
+	Function AsyncEventWaitHandle() As Threading.EventWaitHandle
+		AsyncEventWaitHandle = wait
+	End Function
+Private
+	s As Object
+	res As DWord
+
+	Static wait = Nothing As Threading.EventWaitHandle
+End Class
+
+/*!
+@brief ReadFile/WriteFileのプロトタイプに一致する関数へのポインタ
+@date 2008/08/21
+@auther Egtra
+*/
+TypeDef PIOFile = *Function(h As HANDLE, buf As VoidPtr, bytes As DWord, result As *DWord, ov As *OVERLAPPED) As BOOL
+
+/*!
+@brief BeginOverlappedIoとCallAsyncCallbackとの間で受け渡されるデータの集まり
+@date 2008/08/21
+@auther Egtra
+*/
+Class CallbackData
+Public
+	Callback As AsyncCallback
+	Result As IAsyncResult
+End Class
+
+'---------------------------------------
+
+/*!
+@brief スレッドプールによる非同期IO
+@date 2008/08/21
+@param[in] fn "ReadFile"か"WriteFile"または引数に互換性のあるkernel32の関数名
+@param[in] s 対象のストリーム
+@param[in,out] buffer 入出力先
+@param[in] offset buffer内で入出力を開始する位置
+@param[in] count 読み書きするバイト数
+@param[in] callback 完了したときに呼ばれるデリゲート
+@param[in] state IAsyncResultへの追加引数
+@return EndRead/Writeへの引き換えとなるIAsyncResult
+@auther Egtra
+OVERLAPPED指定無しで開いたファイルの非同期関数用
+*/
+Function ThreadPoolIo(ioType As PCSTR, s As FileStream, buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
+	Dim result = New ThreadPoolIoResult(state)
+	ThreadPoolIo = result
+	Dim d = New ThreadPoolIoData
+	With d
+		.IoType = ioType
+		.Handle = s.Handle
+		.Result = result
+		.Buffer = buffer + offset
+		.Size = count As DWord
+	End With
+	Threading.ThreadPool.QueueUserWorkItem(AddressOf(ThreadIo), d)
+End Function
+
+/*!
+@brief ThreadPoolIo補助で実際に入出力関数を呼ぶ
+@date 2008/08/21
+@auther Egtra
+*/
+Sub ThreadIo(o As Object)
+	Dim d = o As ThreadPoolIoData
+	With d
+		Dim ioFile = GetProcAddress(GetModuleHandle("kernel32.dll"), .IoType) As Detail.PIOFile
+		If ioFile(.Handle, .Buffer, .Size, VarPtr(.Result.Result), 0) = FALSE Then
+			.Result.SetException(Detail.GetWinLastErrorIOException("FileStream.BeginRead/Write"))
+		End If
+		d.Result.AsyncEventWaitHandle.Set()
+		If Not ActiveBasic.IsNothing(.Callback) Then
+			Dim c = .Callback
+			c(.Result)
+		End If
+	End With
+End Sub
+
+/*!
+@brief ThreadPoolIoとThreadIoとの間で受け渡すデータの集まり
+@date 2008/08/21
+@auther Egtra
+*/
+Class ThreadPoolIoData
+Public
+	IoType As PCSTR
+	Handle As HANDLE
+	Result As ThreadPoolIoResult
+	Callback As AsyncCallback
+	Buffer As *Byte
+	Size As DWord
+End Class
+
+End Namespace
+End Namespace
+End Namespace
Index: trunk/ab5.0/ablib/src/Classes/System/IO/MemoryStream.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/MemoryStream.ab	(revision 584)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/MemoryStream.ab	(revision 605)
@@ -173,6 +173,6 @@
 	Virtual Sub Capacity(value As Long)
 		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
-		If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Capacity: A capacity is set to negative value.", New System.Int64(value),"Capacity")
-		If value < This.streamLength Then Throw New ArgumentOutOfRangeException("MemoryStream.Capacity: A capacity is less than the current length of the stream.",New System.Int64(value),"Capacity")
+		If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Capacity: A capacity is set to negative value.", New System.UInt64(value),"Capacity")
+		If value < This.streamLength Then Throw New ArgumentOutOfRangeException("MemoryStream.Capacity: A capacity is less than the current length of the stream.",New System.UInt64(value),"Capacity")
 		This.pointer = This.reallocate(This.pointer,value)
 	End Sub
@@ -193,5 +193,5 @@
 	@date	2008/3/12
 	*/
-	Override Function Length() As Int64
+	Override Function Length() As QWord
 		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
 		Return This.streamLength
@@ -203,8 +203,8 @@
 	@date	2008/3/12
 	*/
-	Override Sub Position(value As Int64)
-		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
-		If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Position: The position is set to a negative value.", New System.Int64(value), "Position")
-		If value > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.Position: The position is a value greater than MaxValue.", New System.Int64(value), "Position")
+	Override Sub Position(value As QWord)
+		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
+		If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Position: The position is set to a negative value.", New System.UInt64(value), "Position")
+		If value > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.Position: The position is a value greater than MaxValue.", New System.UInt64(value), "Position")
 		This.currentPosition = value As Long
 	End Sub
@@ -215,7 +215,7 @@
 	@date	2008/3/12
 	*/
-	Override Function Position() As Int64
-		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
-		Return This.currentPosition As Int64
+	Override Function Position() As QWord
+		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
+		Return This.currentPosition As QWord
 	End Function
 
@@ -236,6 +236,6 @@
 		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
 		If buffer = 0 Then Throw New ArgumentNullException("FileStream.Read: An argument is a null value.", "buffer")
-		If offset < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.Int64(offset), "offset")
-		If count < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.Int64(count), "count")
+		If offset < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.UInt64(offset), "offset")
+		If count < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.UInt64(count), "count")
 		If (This.streamLength - (This.currentPosition + count)) < 0 Then
 			count + = (This.streamLength - (This.currentPosition + count))
@@ -270,5 +270,5 @@
 	Override Function Seek(offset As Int64, origin As SeekOrigin) As Int64
 		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
-		If offset > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.Seek: The offset is a value greater than MaxValue.", New System.Int64(offset), "offset")
+		If offset > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.Seek: The offset is a value greater than MaxValue.", New System.UInt64(offset), "offset")
 		Select Case origin
 			Case SeekOrigin.Begin
@@ -285,5 +285,5 @@
 				Throw New ArgumentException("MemoryStream.Seek: An argument is an invalid SeekOrigin","origin")
 		End Select
-		Return This.currentPosition As Int64
+		Return This.currentPosition As QWord
 	End Function
 
@@ -293,11 +293,11 @@
 	@date	2008/3/12
 	*/
-	Override Sub SetLength(value As Int64)
+	Override Sub SetLength(value As QWord)
 		If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
 		If This.writable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not writable")
 		If This.resizable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not resizable")
 		If value > This.Capacity() Then Throw New NotSupportedException("MemoryStream.SetLength: This stream length is larger than the current capacity.")
-		If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.Int64(value), "value")
-		If value > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.SetLength: The length is a value greater than MaxValue.", New System.Int64(value), "value")
+		If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.UInt64(value), "value")
+		If value > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.SetLength: The length is a value greater than MaxValue.", New System.UInt64(value), "value")
 		This.pointer = This.reallocate(This.pointer,value As Long)
 		This.streamLength = value As Long
@@ -313,9 +313,9 @@
 		If This.writable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not writable")
 		If buffer = 0 Then Throw New ArgumentNullException("MemoryStream.Write: An argument is a null value.", "buffer")
-		If offset < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Write: An argument is a negative value.", New System.Int64(offset), "offset")
-		If count < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Write: An argument is a negative value.", New System.Int64(count), "count")
-		If count > (This.streamLength - This.currentPosition) Then 
+		If offset < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Write: An argument is a negative value.", New System.UInt64(offset), "offset")
+		If count < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Write: An argument is a negative value.", New System.UInt64(count), "count")
+		If count > (This.streamLength - This.currentPosition) Then
 			If This.resizable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not resizable")
-			If (This.Capacity() - This.currentPosition) < count Then 
+			If (This.Capacity() - This.currentPosition) < count Then
 				This.pointer = This.reallocate(This.pointer,This.currentPosition+count)
 			End If
Index: trunk/ab5.0/ablib/src/Classes/System/IO/Stream.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/Stream.ab	(revision 584)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/Stream.ab	(revision 605)
@@ -4,11 +4,11 @@
 
 Class Stream
-	Implements System.IDisposable
+	Implements IDisposable
 
-Public 'Protected
+Protected
 	Sub Stream()
 	End Sub
 Public
-	Virtual Sub ~Stream()
+	Sub ~Stream()
 		This.Dispose(False)
 	End Sub
@@ -18,34 +18,36 @@
 
 	Virtual Function CanTimeout() As Boolean
-		Return True
+		Return False
 	End Function
 
 	Abstract Function CanWrite() As Boolean
-	Abstract Function Length() As Int64
-	Abstract Sub Position(value As Int64)
-	Abstract Function Position() As Int64
+	Abstract Function Length() As QWord
+	Abstract Sub Position(value As QWord)
+	Abstract Function Position() As QWord
 
 	Virtual Sub ReadTimeout(value As Long)
-		' Throw InvalidOperationException
+		Throw New InvalidOperationException("Stream does not support Timeout.")
 	End Sub
 
 	Virtual Function ReadTimeout() As Long
-		' Throw InvalidOperationException
+		Throw New InvalidOperationException("Stream does not support Timeout.")
 	End Function
 
 	Virtual Sub WriteTimeout(value As Long)
-		' Throw InvalidOperationException
+		Throw New InvalidOperationException("Stream does not support Timeout.")
 	End Sub
 
 	Virtual Function WriteTimeout() As Long
-		' Throw InvalidOperationException
+		Throw New InvalidOperationException("Stream does not support Timeout.")
 	End Function
 
 Public
 	Virtual Function BeginRead(buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
-		Read(buffer,offset,count)
+		Dim r = Read(buffer,offset,count)
+		Return New Detail.SyncStreamResultImpl(r, state)
 	End Function
 	Virtual Function BeginWrite(buffer As *Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
 		Write(buffer,offset,count)
+		Return New Detail.SyncStreamResultImpl(0, state)
 	End Function
 	Sub Close()
@@ -56,4 +58,6 @@
 	End Sub
 	Virtual Function EndRead(asyncResult As System.IAsyncResult) As Long
+		Dim ar = asyncResult As Detail.IAsyncStreamResult
+		EndRead = ar.WaitAndGetResult
 	End Function
 	Virtual Sub EndWrite(asyncResult As System.IAsyncResult)
@@ -73,5 +77,5 @@
 
 	Abstract Function Seek(offset As Int64, origin As SeekOrigin) As Int64
-	Abstract Sub SetLength(value As Int64)
+	Abstract Sub SetLength(value As QWord)
 	Abstract Sub Write(buffer As *Byte, offset As Long, count As Long)
 	Virtual Sub WriteByte(b As Byte)
@@ -81,6 +85,4 @@
 	Virtual Sub Dispose(disposing As Boolean)
 	End Sub
-	Virtual Function CreateWaitHandle() As System.Threading.WaitHandle
-	End Function
 End Class
 
Index: trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab	(revision 584)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab	(revision 605)
@@ -34,5 +34,5 @@
 	Override Function Peek() As Long
 		If cur = last Then
-			last = s.Read(buf, 0, size)
+			last = s.Read(buf As *Byte, 0, size)
 			cur = 0
 			If last = 0 Then
@@ -108,5 +108,5 @@
 		If count > size Then
 			n = (count \ size) * size 'sizeの倍数分だけは直接bufferへ読み込ませる
-			Dim read = s.Read(p, 0, n)
+			Dim read = s.Read(p As *Byte, 0, n)
 			If read = 0 Then 'EOF
 				Exit Function
@@ -116,5 +116,5 @@
 			count -= n
 		End If
-		last = s.Read(buffer, 0, size)
+		last = s.Read(buffer As *Byte, 0, size)
 		cur = 0
 		If last = 0 Then 'EOF
Index: trunk/ab5.0/ablib/src/Classes/System/IO/misc.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/IO/misc.ab	(revision 584)
+++ trunk/ab5.0/ablib/src/Classes/System/IO/misc.ab	(revision 605)
@@ -14,4 +14,67 @@
 End Enum
 
+/*
+@brief ファイルのアクセス方法を表す
+*/
+Enum FileAccess
+	Read      = GENERIC_READ
+	ReadWrite = GENERIC_READ Or GENERIC_WRITE
+	Write     = GENERIC_WRITE
+End Enum
+
+/*
+@brief ファイルの属性を表す
+*/
+Enum FileAttributes
+	Archive           = FILE_ATTRIBUTE_ARCHIVE
+	Compressed        = FILE_ATTRIBUTE_COMPRESSED
+	Device            = FILE_ATTRIBUTE_DEVICE
+	Directory         = FILE_ATTRIBUTE_DIRECTORY
+	Encrypted         = FILE_ATTRIBUTE_ENCRYPTED
+	Hidden            = FILE_ATTRIBUTE_HIDDEN
+	Normal            = FILE_ATTRIBUTE_NORMAL
+	NotContentIndexed = FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
+	Offline           = FILE_ATTRIBUTE_OFFLINE
+	ReadOnly          = FILE_ATTRIBUTE_READONLY
+	ReparsePoint      = FILE_ATTRIBUTE_REPARSE_POINT
+	SparseFile        = FILE_ATTRIBUTE_SPARSE_FILE
+	System            = FILE_ATTRIBUTE_SYSTEM
+	Temporary         = FILE_ATTRIBUTE_TEMPORARY
+End Enum
+
+/*
+@brief ファイルの作成モードを表す
+*/
+Enum FileMode
+	Append       = -1
+	Create       = CREATE_ALWAYS
+	CreateNew    = CREATE_NEW
+	Open         = OPEN_EXISTING
+	OpenOrCreate = OPEN_ALWAYS
+	Truncate     = TRUNCATE_EXISTING
+End Enum
+
+/*
+@brief ファイルの共有を表す
+*/
+Enum FileShare
+	None       = 0
+	Read       = FILE_SHARE_READ
+	Write      = FILE_SHARE_WRITE
+	ReadWrite  = FILE_SHARE_READ Or FILE_SHARE_WRITE
+	DeleteFile = FILE_SHARE_DELETE
+	Inheritable = &h10
+End Enum
+
+Enum FileOptions
+	None = 0
+	Asynchronous = FILE_FLAG_OVERLAPPED
+	DeleteOnClose = FILE_FLAG_DELETE_ON_CLOSE
+	Encrypted = FILE_ATTRIBUTE_ENCRYPTED
+	RandomAccess = FILE_FLAG_RANDOM_ACCESS
+	SequentialScan = FILE_FLAG_SEQUENTIAL_SCAN
+	WriteThrough = FILE_FLAG_WRITE_THROUGH
+End Enum
+
 End Namespace 'IO
 End Namespace 'System
