8k? Dann fehlt da wohl einiges
Code:
Imports System.IO
Imports System.Net
Imports System.Collections.Generic
Imports System.Text
Module Module1
Class Foo ' Zum Debuggen
Protected mWritten As Long
Protected mStream As Stream
Public Sub New(ByVal target As Stream)
mStream = target
mWritten = 0
End Sub
Public Sub Write(ByRef buffer() As Byte, ByVal offset As Integer, ByVal count As Integer)
mStream.Write(buffer, offset, count)
mWritten += count
' Debug.Write(Encoding.ASCII.GetString(buffer, 0, buffer.Length))
End Sub
Public Sub Close()
mStream.Close()
End Sub
Public ReadOnly Property Length()
Get
Return mWritten
End Get
End Property
End Class
Class FileMimePart
Public Shared BufferSize As Integer = 2048
Dim mFilename As String
Dim mElementname As String
Dim mStream As FileStream
Dim mStreamLength As Long
Dim mHeader() As Byte = Nothing
Public Sub New(ByVal filename As String, ByVal elementname As String)
mStream = New FileStream(filename, FileMode.Open, FileAccess.Read)
If False = mStream.CanSeek Then
Throw New IOException("!stream.CanSeek")
End If
mStreamLength = mStream.Length
mFilename = filename
mElementname = elementname
mHeader = createHeader()
End Sub
Public ReadOnly Property Length() As Long
Get
Return mHeader.Length + mStreamLength
End Get
End Property
Public Function WriteTo(ByRef target As Foo) As Long
Dim total As Long = 0
Dim buffSize As Integer = CType(Math.Min(BufferSize, mStream.Length), Integer)
Dim buffer(buffSize) As Byte
Dim cbRead As Integer
mStream.Position = 0
Dim s As String = String.Format("WriteTo: filename={0} part-lenght={1:D} mLength={2:D} stream.length={3:D}", mFilename, Length, mStreamLength, mStream.Length)
Debug.WriteLine(s)
If mStreamLength <> mStream.Length Then
Throw New IOException("file changed")
End If
target.Write(mHeader, 0, mHeader.Length)
total += mHeader.Length
cbRead = mStream.Read(buffer, 0, buffer.Length)
While cbRead > 0
target.Write(buffer, 0, cbRead)
total += cbRead
cbRead = mStream.Read(buffer, 0, buffer.Length)
End While
If total <> Length Then
Throw New IOException("total <> Length")
End If
Return total
End Function
Protected Function createHeader() As Byte()
Return Encoding.UTF8.GetBytes( _
"Content-Disposition: form-data; name=""" & mElementname & """; filename=""" & Path.GetFileName(mFilename) & """" & ControlChars.CrLf _
& "Content-Type: text/plain" & ControlChars.CrLf _
& ControlChars.CrLf _
)
End Function
End Class
Public Class FileUpload
Dim mBoundary As String
Dim mHeader() As Byte
Dim mCrLf() As Byte
Dim mFooter() As Byte
Dim files As List(Of FileMimePart) = New List(Of FileMimePart)
Public Sub New()
mBoundary = "---------------------------" & Now.Ticks.ToString() & CType(Threading.Thread.CurrentThread.ManagedThreadId, String)
mHeader = Encoding.ASCII.GetBytes("--" & mBoundary & ControlChars.CrLf)
mCrLf = Encoding.ASCII.GetBytes(ControlChars.CrLf)
mFooter = Encoding.ASCII.GetBytes("--" & mBoundary & "--" & ControlChars.CrLf)
End Sub
Public Sub AddFile(ByVal filename As String, ByVal elementname As String)
files.Add(New FileMimePart(filename, elementname))
End Sub
Public Function SendTo(ByVal url As String) As HttpWebResponse
Dim request As HttpWebRequest = HttpWebRequest.Create(url)
request.AllowWriteStreamBuffering = True
request.Method = "POST"
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 (.NET CLR 3.5.30729)"
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
request.ContentType = "multipart/form-data; boundary=" & mBoundary
request.ContentLength = ContentLength
Debug.WriteLine("request.ContentLength=" & request.ContentLength.ToString())
Dim stream As Foo = New Foo(request.GetRequestStream())
For Each fmp As FileMimePart In files
stream.Write(mHeader, 0, mHeader.Length)
fmp.WriteTo(stream)
stream.Write(mCrLf, 0, mCrLf.Length)
Next
stream.Write(mFooter, 0, mFooter.Length)
Dim dbgWritten = stream.Length
stream.Close()
Return CType(request.GetResponse(), HttpWebResponse)
End Function
Public ReadOnly Property ContentLength() As Long
Get
Dim length As Integer = 0
For Each fmp As FileMimePart In files
length += mHeader.Length + fmp.Length + mCrLf.Length
Next
length += mFooter.Length
Return length
End Get
End Property
End Class
Function getFirstStorageCardPath()
Dim sPath As String = ""
Dim attrStorageCard As FileAttributes = FileAttributes.Directory Or FileAttributes.Temporary
Dim root As DirectoryInfo = New DirectoryInfo("\")
For Each fsi As FileSystemInfo In root.GetFileSystemInfos()
If attrStorageCard = (fsi.Attributes And attrStorageCard) Then
sPath = fsi.FullName
Exit For
End If
Next
Return sPath
End Function
Sub Stream2DebugConsole(ByVal source As Stream)
Dim buffer(8192) As Byte
Dim cbRead As Integer
Debug.WriteLine(ControlChars.CrLf & "stream:")
cbRead = source.Read(buffer, 0, buffer.Length)
While cbRead > 0
Debug.Write(Encoding.ASCII.GetString(buffer, 0, cbRead))
cbRead = source.Read(buffer, 0, buffer.Length)
End While
Debug.WriteLine(ControlChars.CrLf & "done.")
End Sub
Sub Main()
System.Net.ServicePointManager.Expect100Continue = False
Dim base As String = getFirstStorageCardPath()
Dim upload As FileUpload = New FileUpload
upload.AddFile(base & "\FileZilla_3.2.0_win32-setup.exe", "file1")
upload.AddFile(base & "\php-5.2.6.tar.bz2", "file2")
Dim response As HttpWebResponse = upload.SendTo("http://10.0.10.1/test.php")
Dim rstream As Stream = response.GetResponseStream()
Stream2DebugConsole(rstream)
Return
End Sub
End Module
edit: Es geht mir um diesen (geänderten)Teil:
Code:
Public Function WriteTo(ByRef target As Foo) As Long
Dim total As Long = 0
Dim buffSize As Integer = CType(Math.Min(BufferSize, mStream.Length), Integer)
Dim buffer(buffSize) As Byte
Dim cbRead As Integer
mStream.Position = 0
Dim s As String = String.Format("WriteTo: filename={0} part-lenght={1:D} mLength={2:D} stream.length={3:D}", mFilename, Length, mStreamLength, mStream.Length)
Debug.WriteLine(s)
If mStreamLength <> mStream.Length Then
Throw New IOException("file changed")
End If
target.Write(mHeader, 0, mHeader.Length)
total += mHeader.Length
cbRead = mStream.Read(buffer, 0, buffer.Length)
While cbRead > 0
target.Write(buffer, 0, cbRead)
total += cbRead
cbRead = mStream.Read(buffer, 0, buffer.Length)
End While
If total <> Length Then
Throw New IOException("total <> Length")
End If
Return total
End Function