Related
I have a problem to record the image in the SQL_database in vb.net.Enter as a file without a problem but I can not write in SQL.ABCreateNewBarcode is a PictureBox. I have a problem to take BackgroundImage from PictureBox to save in SQL. I save BackgroundImage in BarcodeImg folder but I can not save in SQl
Private Sub btnSaveBarcode_Click(sender As Object, e As EventArgs) Handles btnSaveBarcode.Click
'Create Image Object
Dim ABCreateNewBarcode As Object
ABCreateNewBarcode = CreateObject("BARCODE.BarcodeCtrl.1")
ABCreateNewBarcode.Text = txtNewBarcode.Text
ABCreateNewBarcode.typename = "Code128"
DirBarcodeImg = Application.StartupPath & "\barcodeimg"
'Save Image
If txtNewBarcode.Text = "" Then
MsgBox("Click the Create Button to create a New Barcode")
ElseIf Directory.Exists(DirBarcodeImg) = False Then
Call Directory.CreateDirectory(DirBarcodeImg)
Else
ABCreateNewBarcode.SaveAsBySize(DirBarcodeImg & "\" & txtInsertPartName.Text & ".png", 300, 130)
Dim ImageToSave As Image = ABCreateNewBarcode.BackgroundImage
Dim ms As New MemoryStream
ImageToSave.Save(ms, ImageToSave.RawFormat)
Dim buffer As Byte() = MS.GetBuffer()
'Add SQL Parameters
SQL.AddParam("#name", txtInsertPartName.Text)
SQL.AddParam("#image", buffer)
'Run Imsert Command
SQL.ExecQuery("INSERT INTRO information (PartName,BarcodeImg) " &
"VALUES (#name,#image) ")
End If
End Sub
After chaging you request "INTO" instead of "INTRO" try this line:
SQL.Parameters.AddWithValue("#image", txtInsertPartName.Text).SqlDbType = SqlDbType.Image
and replace :
Dim ms As New MemoryStream
ImageToSave.Save(ms, ImageToSave.RawFormat)
Dim buffer As Byte() = MS.GetBuffer()
by this:
Dim fs As FileStream
fs = New FileStream(imagename, FileMode.Open, FileAccess.Read)
'a byte array to read the image
Dim picbyte As Byte() = New Byte(fs.Length - 1) {}
fs.Read(picbyte, 0, System.Convert.ToInt32(fs.Length))
fs.Close()
'open the database using odp.net and insert the data
Dim buffer As Byte() =picbyte
I'm coding an application that uploads a file to a remote FTP server. This is my code that already works.
clsrequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim bFile() As Byte = System.IO.File.ReadAllBytes(rutaorigen)
Dim clsStream As System.IO.Stream = clsrequest.GetRequestStream()
clsStream.Write(bFile, 0, bFile.Length)
clsStream.Close()
clsStream.Dispose()
Now I want to show the progress in a ProgressBar in VB.NET.
Files are not too big (10 MB max).
I've already tried an example that I found here, but it didn't work.
I hope you can help me. Thanks!
Simple progress on console:
Dim request As WebRequest = WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip")
request.Credentials = New NetworkCredential("username", "password")
request.Method = WebRequestMethods.Ftp.UploadFile
Using fileStream As Stream = File.OpenRead("C:\local\path\file.zip"),
ftpStream As Stream = request.GetRequestStream()
Dim buffer As Byte() = New Byte(10240 - 1) {}
Dim read As Integer
Do
read = fileStream.Read(buffer, 0, buffer.Length)
If read > 0 Then
ftpStream.Write(buffer, 0, read)
Console.WriteLine("Uploaded {0} bytes", fileStream.Position)
End If
Loop While read > 0
End Using
WinForms GUI progress:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Run Upload on background thread
Task.Run((Sub() Upload()))
End Sub
Sub Upload()
Dim request As WebRequest =
WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip")
request.Credentials = New NetworkCredential("username", "password")
request.Method = WebRequestMethods.Ftp.UploadFile
Using fileStream As Stream = File.OpenRead("C:\local\path\file.zip"),
ftpStream As Stream = request.GetRequestStream()
ProgressBar1.Invoke(Sub() ProgressBar1.Maximum = fileStream.Length)
Dim buffer As Byte() = New Byte(10240 - 1) {}
Dim read As Integer
Do
read = fileStream.Read(buffer, 0, buffer.Length)
If read > 0 Then
ftpStream.Write(buffer, 0, read)
ProgressBar1.Invoke(Sub() ProgressBar1.Value = fileStream.Position)
End If
Loop While read > 0
End Using
End Sub
I got this from an example a long time ago. The code should be fairly easy to change for your needs.
Dim clsRequest As System.Net.FtpWebRequest = _
DirectCast(System.Net.WebRequest.Create(ServLabel.Text & TextBox1.Text), System.Net.FtpWebRequest)
clsRequest.Credentials = New System.Net.NetworkCredential(PassLabel.Text, UserLabel.Text)
clsRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile
rfshTMR.Enabled = True
Dim File() As Byte = System.IO.File.ReadAllBytes(txtFile.Text)
Dim clsStream As System.IO.Stream = _
clsRequest.GetRequestStream()
clsStream.Write(File, 0, File.Length)
For offset As Integer = 0 To File.Length Step 1024
ToolStripProgressBar1.Value = CType(offset * ToolStripProgressBar1.Maximum / File.Length, Integer)
Dim chunkSize As Integer = File.Length - offset - 1
If chunkSize > 1024 Then chunkSize = 1024
clsStream.Write(File, offset, chunkSize)
ToolStripProgressBar1.Value = ToolStripProgressBar1.Maximum
Next
clsStream.Close()
clsStream.Dispose()
MsgBox("File Is Now In Database", MsgBoxStyle.OkOnly, "Upload Complete")
I have this code which works well:
Public Function LoadBinaryFile(strFilename As String) As Byte()
Using fsSource As FileStream = New FileStream(strFilename, FileMode.Open, FileAccess.Read)
' Read the source file into a byte array.
Dim bytes() As Byte = New Byte((fsSource.Length) - 1) {}
Dim numBytesToRead As Integer = CType(fsSource.Length, Integer)
Dim numBytesRead As Integer = 0
'tsProgressBar.Minimum = 0
'tsProgressBar.Maximum = numBytesToRead
While (numBytesToRead > 0)
' Read may return anything from 0 to numBytesToRead.
Dim n As Integer = fsSource.Read(bytes, numBytesRead, _
numBytesToRead)
' Break when the end of the file is reached.
If (n = 0) Then
Exit While
End If
numBytesRead = (numBytesRead + n)
numBytesToRead = (numBytesToRead - n)
'tsProgressBar.Value = numBytesRead
End While
numBytesToRead = bytes.Length
Return bytes
End Using
End Function
And I have this code to save the file which also works well:
Public Function SaveBinaryFile(strFilename As String, bytesToWrite() As Byte) As Boolean
Using fsNew As FileStream = New FileStream(strFilename, FileMode.Create, FileAccess.Write)
fsNew.Write(bytesToWrite, 0, bytesToWrite.Length)
End Using
End Function
What I am after is some help to modify the SaveBinaryFile function to implement a progress bar.
Final:
OK, I have written the function myself. Here it is:
Public Function ReadBinaryFile(strFilename As String) As Byte()
Dim position As Integer = 0
Dim bufferSize As Integer = 4096
Dim bytes() As Byte
'frmMain.tsProgressBar.Value = 0
Using fsOpen As FileStream = New FileStream(strFilename, FileMode.Open)
redim bytes((fsOpen.Length) - 1)
Do
If (position + bufferSize) > fsOpen.Length Then
fsOpen.Read(bytes, position, fsOpen.Length - position)
Exit Do
Else
fsOpen.Read(bytes, position, bufferSize)
End If
'frmMain.tsProgressBar.Value = ((position / fsOpen.Length) * 100)
'frmMain.tsProgressBar.Refresh()
Application.DoEvents()
position += bufferSize
Loop
End Using
Return bytes
End Function
My.Computer.Filesystem.ReadAllBytes("filename") reads the entire file into a byte array.
My.Computer.Filesystem.WriteAllBytes("filename", bytes, false) writes it back.
I've never tried using the Async options on FileStream but there don't seem to be any event handlers.
I would break it down into a loop, you have the total amount of bytes to write so you could loop through writing 4k at a time, update your progress bar and continue the loop.
Public Sub SaveBinaryFile(strFilename As String, bytesToWrite() As Byte)
Dim position As Integer = 0
Using fsNew As FileStream = New FileStream(strFilename, FileMode.Create, FileAccess.Write)
Do
Dim intToCopy As Integer = Math.Min(4096, bytesToWrite.Length - position)
Dim buffer(intToCopy - 1) As Byte
Array.Copy(bytesToWrite, position, buffer, 0, intToCopy)
fsNew.Write(buffer, 0, buffer.Length)
ProgressBar1.Value = ((position / bytesToWrite.Length) * 100)
Application.DoEvents()
position += intToCopy
Loop While position < bytesToWrite.Length
End Using
End Sub
'Or, if you are reading a file from a URL, here is a way to read the file into an array of bytes.
Dim WebRequest As Net.HttpWebRequest = Net.WebRequest.Create("http://mypage.abc.com/myfolder/MyFileName.xls")
Using WBinReader As BinaryReader = New BinaryReader(WRequest.GetResponse.GetResponseStream)
Dim file_buffer() As Byte
'10000000 is an arbitrary number, but File_Buffer will have no more
'elements than they number of bytes in the URL's file.
file_buffer = WBinReader.ReadBytes(10000000)
file_bytes =UBound(buffer)+1
End Using
Brian Jasmer
I'm having some trouble with this, despite finding examples. I think it may be an encoding problem, but I'm just not sure. I am trying to programitally download a file from a https server, that uses cookies (and hence I'm using httpwebrequest). I'm debug printing the capacity of the streams to check, but the output [raw] files look different. Have tried other encoding to no avail.
Code:
Sub downloadzip(strURL As String, strDestDir As String)
Dim request As HttpWebRequest
Dim response As HttpWebResponse
request = Net.HttpWebRequest.Create(strURL)
request.UserAgent = strUserAgent
request.Method = "GET"
request.CookieContainer = cookieJar
response = request.GetResponse()
If response.ContentType = "application/zip" Then
Debug.WriteLine("Is Zip")
Else
Debug.WriteLine("Is NOT Zip: is " + response.ContentType.ToString)
Exit Sub
End If
Dim intLen As Int64 = response.ContentLength
Debug.WriteLine("response length: " + intLen.ToString)
Using srStreamRemote As StreamReader = New StreamReader(response.GetResponseStream(), Encoding.Default)
'Using ms As New MemoryStream(intLen)
Dim fullfile As String = srStreamRemote.ReadToEnd
Dim memstream As MemoryStream = New MemoryStream(New UnicodeEncoding().GetBytes(fullfile))
'test write out to flie
Dim data As Byte() = memstream.ToArray()
Using filestrm As FileStream = New FileStream("c:\temp\debug.zip", FileMode.Create)
filestrm.Write(data, 0, data.Length)
End Using
Debug.WriteLine("Memstream capacity " + memstream.Capacity.ToString)
'Dim strData As String = srStreamRemote.ReadToEnd
memstream.Seek(0, 0)
Dim buffer As Byte() = New Byte(2048) {}
Using zip As New ZipInputStream(memstream)
Debug.WriteLine("zip stream cap " + zip.Length.ToString)
zip.Seek(0, 0)
Dim e As ZipEntry
Dim flag As Boolean = True
Do While flag ' daft, but won't assign e=zip... tries to evaluate
e = zip.GetNextEntry
If IsNothing(e) Then
flag = False
Exit Do
Else
e.UseUnicodeAsNecessary = True
End If
If Not e.IsDirectory Then
Debug.WriteLine("Writing out " + e.FileName)
' e.Extract(strDestDir)
Using output As FileStream = File.Open(Path.Combine(strDestDir, e.FileName), _
FileMode.Create, FileAccess.ReadWrite)
Dim n As Integer
Do While (n = zip.Read(buffer, 0, buffer.Length) > 0)
output.Write(buffer, 0, n)
Loop
End Using
End If
Loop
End Using
'End Using
End Using 'srStreamRemote.Close()
response.Close()
End Sub
So I get the right size file downloaded, but dotnetzip does not recognise it, and the files that get copied out are incomplete/invalid zips. I've spent most of today on this, and am ready to give up.
I think the answer will be to break down the problem, and perhaps change a couple aspects in the code.
For example, lets get rid of converting the response stream to a string:
Dim memStream As MemoryStream
Using rdr As System.IO.Stream = response.GetResponseStream
Dim count = Convert.ToInt32(response.ContentLength)
Dim buffer = New Byte(count) {}
Dim bytesRead As Integer
Do
bytesRead += rdr.Read(buffer, bytesRead, count - bytesRead)
Loop Until bytesRead = count
rdr.Close()
memStream = New MemoryStream(buffer)
End Using
Next, there's an easier way to output the contents of a memory stream to a file. Consider your code
Dim data As Byte() = memstream.ToArray()
Using filestrm As FileStream = New FileStream("c:\temp\debug.zip", FileMode.Create)
filestrm.Write(data, 0, data.Length)
End Using
can be replaced with
Using filestrm As FileStream = New FileStream("c:\temp\debug.zip", FileMode.Create)
memstream.WriteTo(filestrm)
End Using
That eliminates the need to transfer your memory stream into another byte array, and then push the byte array down the stream, when in fact the memory stream can transfer data directly to file (via the filestream) saving the middle-man buffer.
I'll admit I haven't worked with the Zip/compression libraries you're using, but with the above amendments you have removed unnecessary transfers between streams, byte arrays, strings, etc, and hopefully eliminated the encoding issues you were having.
Give that a try and let us know how you get on. Consider attempting to open the file that you saved ("C:\temp\debug.zip") to see if it is listed as corrupt. If not, then you know at least as far as that in the code, it is working ok.
I thought I'd post my full working solution to my own question, it combines the two excellent replies I've had, thank you guys.
Sub downloadzip(strURL As String, strDestDir As String)
Try
Dim request As HttpWebRequest
Dim response As HttpWebResponse
request = Net.HttpWebRequest.Create(strURL)
request.UserAgent = strUserAgent
request.Method = "GET"
request.CookieContainer = cookieJar
response = request.GetResponse()
If response.ContentType = "application/zip" Then
Debug.WriteLine("Is Zip")
Else
Debug.WriteLine("Is NOT Zip: is " + response.ContentType.ToString)
Exit Sub
End If
Dim intLen As Int32 = response.ContentLength
Debug.WriteLine("response length: " + intLen.ToString)
Dim memStream As MemoryStream
Using stmResponse As IO.Stream = response.GetResponseStream()
'Using ms As New MemoryStream(intLen)
Dim buffer = New Byte(intLen) {}
'Dim memstream As MemoryStream = New MemoryStream(buffer)
Dim bytesRead As Integer
Do
bytesRead += stmResponse.Read(buffer, bytesRead, intLen - bytesRead)
Loop Until bytesRead = intLen
memStream = New MemoryStream(buffer)
Dim res As Boolean = False
res = ZipExtracttoFile(memStream, strDestDir)
End Using 'srStreamRemote.Close()
response.Close()
Catch ex As Exception
'to do :)
End Try
End Sub
Function ZipExtracttoFile(strm As MemoryStream, strDestDir As String) As Boolean
Try
Using zip As ZipFile = ZipFile.Read(strm)
For Each e As ZipEntry In zip
e.Extract(strDestDir)
Next
End Using
Catch ex As Exception
Return False
End Try
Return True
End Function
You can download into a MemoryStream, then examine it:
Public Sub Download(url as String)
Dim req As HttpWebRequest = System.Net.WebRequest.Create(url)
req.Method = "GET"
Dim resp As HttpWebResponse = req.GetResponse()
If resp.ContentType = "application/zip" Then
Console.Error.Write("The result is a zip file.")
Dim length As Int64 = resp.ContentLength
If length = -1 Then
Console.Error.WriteLine("... length unspecified")
length = 16 * 1024
Else
Console.Error.WriteLine("... has length {0}", length)
End If
Dim ms As New MemoryStream
CopyStream(resp.GetResponseStream(), ms) '' **see note below!!!!
'' list contents of the zip file
ms.Seek(0,SeekOrigin.Begin)
Using zip As ZipFile = ZipFile.Read (ms)
Dim e As ZipEntry
Console.Error.WriteLine("Entries:")
Console.Error.WriteLine(" {0,22} {1,10} {2,12}", _
"Name", "compressed", "uncompressed")
Console.Error.WriteLine("----------------------------------------------------")
For Each e In zip
Console.Error.WriteLine(" {0,22} {1,10} {2,12}", _
e.FileName, _
e.CompressedSize, _
e.UncompressedSize)
Next
End Using
Else
Console.Error.WriteLine("The result is Not a zip file.")
CopyStream(resp.GetResponseStream(), Console.OpenStandardOutput)
End If
End Sub
Private Shared Sub CopyStream(input As Stream, output As Stream)
Dim buffer(32768 - 1) As Byte
Dim n As Int32
Do
n = input.Read(buffer, 0, buffer.Length)
If n = 0 Then Exit Do
output.Write(buffer, 0, n)
Loop
End Sub
EDIT
Just one note - I would not advise using this code (this approach) if the Zip file is very large. How large is "very large"? Well that depends, of course. The code I suggested above downloads the file into a memory stream, which of course means the entire contents of the zip file are held in memory. If it is a 28kb zip file, then there's no problem. But if it is a 2gb zip file, then you may have a big problem.
In that case you will want to stream it to a temporary file on disk, not to a MemoryStream. I'll leave that as an exercise for the reader.
The above will work for "reasonably sized" zip files, where "reasonable" depends on your machine configuration and application scenario.
I'm trying to make rijndael work in CBC mode. I'm not exactly sure how should I do it. I think problem in my current code is that the stream is initialized every time in the beginning of encryption, so no avalanche effect occurs (same data is encrypted twice and the output of those two encryption is the same which it should not be).
I tried to initialize the cryptostream only once but then my coded crashed because the canwrite property of cryptostream goes to false after the first write to the cryptostream.
Here is the code what I have now:
Sub Main()
Dim rij As New RijndaelManaged
Dim iv(15) As Byte
Dim key(15) As Byte
Dim secret() As Byte = {59, 60, 61}
Dim cs As ICryptoTransform
Dim cstream As CryptoStream
Dim out() As Byte
Dim NewRandom As New RNGCryptoServiceProvider()
NewRandom.GetBytes(iv)
NewRandom.GetBytes(key)
rij = New RijndaelManaged()
rij.KeySize = 128
rij.Padding = PaddingMode.PKCS7
rij.Mode = CipherMode.CBC
rij.IV = iv
rij.Key = key
cs = rij.CreateEncryptor()
Dim ms_in As New MemoryStream
cstream = New CryptoStream(ms_in, cs, CryptoStreamMode.Write)
Using cstream
cstream.Write(secret, 0, 3)
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length))
Erase out
ms_in = New MemoryStream
cstream = New CryptoStream(ms_in, cs, CryptoStreamMode.Write)
Using cstream
cstream.Write(secret, 0, 3)
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length))
End Sub
and the conversion function to convert an array to string
Public Function ArrayToString(ByVal bytes() As Byte, ByVal length As Integer) As String
If bytes.Length = 0 Then Return String.Empty
Dim sb As New System.Text.StringBuilder(length)
Dim k As Integer = length - 1
Dim i As Integer
For i = 0 To k
sb.Append(Chr(bytes(i)))
Next
Return sb.ToString()
End Function
This is what I need:
cs = rij.CreateEncryptor()
Dim ms_in As New MemoryStream
cstream = New CryptoStream(ms_in, cs, CryptoStreamMode.Write)
Using cstream
cstream.Write(secret, 0, 3) 'encrypt
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length)) 'see the encrypted message
Erase out
Using cstream
cstream.Write(secret, 0, 3) 'encrypt, this will crash here and this is the problem I'm trying to solve
End Using
out = ms_in.ToArray
Console.WriteLine(ArrayToString(out, out.Length)) 'see the encrypted message this should not be the same as the first one
Try this:
Public Sub Run()
Dim key() As Byte = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
Dim plaintext1 As Byte() = {59, 60, 61}
Dim plaintext2 As Byte() = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, _
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, _
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, _
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 _
}
Roundtrip(plaintext1, key)
System.Console.WriteLine()
Roundtrip(plaintext2, key)
End Sub
Public Sub Roundtrip(ByRef plaintext As Byte(), ByRef key As Byte())
Dim rij As New RijndaelManaged
Dim iv(15) As Byte
Dim encryptor As ICryptoTransform
Dim decryptor As ICryptoTransform
Dim out() As Byte
'Dim NewRandom As New RNGCryptoServiceProvider()
'NewRandom.GetBytes(iv)
'NewRandom.GetBytes(key)
Console.WriteLine("Original:")
Console.WriteLine(ArrayToString(plaintext))
System.Console.WriteLine()
rij = New RijndaelManaged()
rij.KeySize = key.Length * 8 ' 16 byte key == 128 bits
rij.Padding = PaddingMode.PKCS7
rij.Mode = CipherMode.CBC
rij.IV = iv
rij.Key = key
encryptor = rij.CreateEncryptor()
Using msIn = New MemoryStream
Using cstream = New CryptoStream(msIn, encryptor, CryptoStreamMode.Write)
cstream.Write(plaintext, 0, plaintext.Length)
End Using
out = msIn.ToArray
Console.WriteLine("Encrypted:")
Console.WriteLine("{0}", ArrayToString(out))
System.Console.WriteLine()
End Using
decryptor = rij.CreateDecryptor()
Using msIn = New MemoryStream
Using cstream = New CryptoStream(msIn, decryptor, CryptoStreamMode.Write)
cstream.Write(out, 0, out.Length)
End Using
out = msIn.ToArray
Console.WriteLine("Decrypted: ")
Console.WriteLine("{0}", ArrayToString(out))
System.Console.WriteLine()
End Using
End Sub
Public Shared Function ArrayToString(ByVal bytes As Byte()) As String
Dim sb As New System.Text.StringBuilder()
Dim i As Integer
For i = 0 To bytes.Length-1
if (i <> 0 AND i mod 16 = 0) Then
sb.Append(Environment.NewLine)
End If
sb.Append(System.String.Format("{0:X2} ", bytes(i)))
Next
Return sb.ToString().Trim()
End Function
I made these basic changes to get it to work:
create a Decryptor
properly manage buffers and streams (see the Using clauses I added)
I also re-organized a little, and modified your code slightly to use a constant IV (all zeros) and use a constant key. This is so that you can get repeatable results from one run to the next. In a real app you would use a randomized IV and use a password-derived key. (See Rfc2898DeriveBytes)
ok, that allows the code to compile. I think you want to see the effect of chaining. That is not so easy, but maybe something like this will show you what you want to see:
For i As Integer = 1 To 2
Using ms = New MemoryStream
Using cstream = New CryptoStream(ms, encryptor, CryptoStreamMode.Write)
For j As Integer = 1 To i
cstream.Write(plaintext, 0, plaintext.Length)
Next j
End Using
out = ms.ToArray
Console.WriteLine("Encrypted (cycle {0}):", i)
Console.WriteLine("{0}", ArrayToString(out))
System.Console.WriteLine()
End Using
Next i