Read binary file from database but don't save it - sql-server

I wrote a windows form program in VB
In the from of my Project I want if a button is clicked, show a file (pdf or word) that save in database. I use this code for doing it and this code works fine. but files are copied in my bin folder of project. I want that these files only show on screen but not saved anywhere. Can anyone help me?
Try
Using dr As SqlDataReader = cmd.ExecuteReader()
While dr.Read()
Dim size As Integer = 1024 * 1024
Dim buffer As Byte() = New Byte(size - 1) {}
Dim readBytes As Integer = 0
Dim index As Integer = 0
filename = dr("DocName")
Using fs As New FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None)
While (InlineAssignHelper(readBytes, CInt(dr.GetBytes(0, index, buffer, 0, size)))) > 0
fs.Write(buffer, 0, readBytes)
index += readBytes
End While
End Using
End While
End Using
Catch ex As Exception
Dim errMessageBox As New Puzzle.ErrorHandler
errMessageBox.ShowError("Err", "FrmCustomer:DbTools_GetAttachFile", "line", ex.Message)
Exit Sub
Finally
ConImage.Close()
End Try
End Using
Dim prc As New Process()
prc.StartInfo.FileName = filename
prc.Start()

Just modify the following line, and it should work.
'filename = dr("DocName") ' replace this line
filename = IO.Path.GetTempFileName ' with this
Basically, IO.Path.GetTempFileName will get a temporary filename in the Windows Temp folder. This folder is used for keeping temporary files and is usually cleaned by various disk cleaning tools automatically or when you ask windows to reclaim wasted space (via Disk Cleanup program).
Note that you would need the same filename when opening the file.

Related

How to fix 'Index was outside of bounds of the array'

Using visual basic. Trying to load a series of reports onto a listview, listview consists of 3 columns (location, date and severity level) everytime it loads it crashes due to 'index being outside the bounds of the array'.Specifically around DOI = reportdetails(1) in my code. It is loading off of a textfile. I have the data within the textfile so I am unsure of why it is saying I am asking for information that doesnt exist. The program also encypts the textfile.
Dim locate, DOI, SeverityLevel, ReportTitles, EReportTitles, ReportDetails(2) As String
Dim Index As Integer 'Define Variables
Dim FileNum As Integer = FreeFile()
Dim IncidentReport As ListViewItem
lstReports.Items.Clear()
If Dir("ReportTitles.txt") <> "" Then 'If the directory of the file exits then continue
FileOpen(FileNum, "ReportTitles.txt", OpenMode.Input) 'open file
Do Until EOF(FileNum) 'Repeat until the end of the file is reached
EReportTitles = "" 'Clear variables, to safeguard against crashes or errors
ReportTitles = ""
EReportTitles = LineInput(FileNum) 'EReportTitles is equal to the current file line
Dim FileName As String = "ReportTitles.txt" 'Define variables
Dim I, C As Integer
Dim Last As Integer = EReportTitles.Length - 1
Dim ThisChar As Char
For I = 0 To Last 'Begin for loop
ThisChar = EReportTitles.Chars(I) 'Decryption of file
C = Asc(ThisChar) Xor 22
ThisChar = Chr(C)
ReportTitles += ThisChar
Next
If ReportTitles <> "" Then
ReportDetails = Split(ReportTitles, ",") 'Split the lines when a "," is encountered
locate = ReportDetails(0) 'Assosciate to relevant value in array
DOI = ReportDetails(1)
SeverityLevel = ReportDetails(2)
IncidentReport = New ListViewItem
IncidentReport.Text = locate 'Add relevant values to IncidentReport ListViewItem variable
IncidentReport.SubItems.Add(DOI)
IncidentReport.SubItems.Add(SeverityLevel)
lstReports.Items.Add(IncidentReport) 'Transfer IncidentReport to listview
Else
End If
Loop
FileClose(FileNum) 'close file
End If
Expected result is to load all of the report location, dates and severity levels onto the listview.
Also sorry about the formatting of this question, i'm new to stack overflow.
There's no point declaring ReportDetails like this:
ReportDetails(2) As String
because that creates an array that you never use. Here:
ReportDetails = Split(ReportTitles, ",")
you are creating a new array anyway and the length of that array will be determined by the number of delimiters in ReportTitles. If you're being told that 1 is an invalid index for that array then that array must only contain 1 element, which means that ReportTitles didn't contain any delimiters.
This is not something that we should have to explain to you because you can easily see it for yourself by debugging and you should ALWAYS debug BEFORE posting here. Set a breakpoint at the top of the code, step through it line by line and examine the state at each step. You can easily see the contents of ReportTitles and ReportDetails and anything else to see whether they are what you expect them to be.
If the point here is to read a CSV file then you really ought to be using the TextFieldParser class. The documentation for that class includes a code example.
This requires .Net Standard 2.1, and so I'm not sure if VB.Net can use the required SpanAction for the String.Create() method, but if it is supported it should greatly outperform the original.
lstReports.Items.Clear()
'Read and "Decrypt" (and I use that term loosely) the file with only a single heap allocation
Dim file As String
Using fs As FileStream = File.OpenRead("ReportTitles.txt")
file = String.Create(fs.Length, fs,
Sub(chars, stream)
For i As Integer = 0 To stream.Length - 1
'THIS IS NOT ENCRYPTION! At best, it's obfuscation.
chars(i) = Chr(fs.ReadByte() Xor 22)
Next
End Sub)
End Using
'Use an actual CSV parser
Using reader As New StringReader(file), _
parser As New TextFieldParser(reader)
parser.TextFieldType = FileIO.FieldType.Delimited
parser.Delimiters = New String() {","}
Dim row As String()
While Not parser.EndOfData
row = parser.ReadFields()
If row.Length >= 3 Then
Dim IncidentReport As New ListViewItem()
IncidentReport.Text = row(0) '
IncidentReport.SubItems.Add(row(1))
IncidentReport.SubItems.Add(row(2))
lstReports.Items.Add(IncidentReport)
End If
End While
End Using
If you are not able to use that version, this is not quite as good, but still a better approach than the original:
lstReports.Items.Clear()
'Load and "Decrypt" the file
Dim file As String
Using fs As FileStream = File.OpenRead("ReportTitles.txt")
Dim builder As New StringBuilder(fs.Length)
For i As Integer = 0 To fs.Length - 1
'THIS IS NOT ENCRYPTION! At best, it's obfuscation.
builder.Append(Chr(fs.ReadByte() Xor 22))
Next
file = builder.ToString()
End Using
'Use an actual CSV parser
Using reader As New StringReader(file), _
parser As New TextFieldParser(reader)
parser.TextFieldType = FileIO.FieldType.Delimited
parser.Delimiters = New String() {","}
Dim row As String()
While Not parser.EndOfData
row = parser.ReadFields()
If row.Length >= 3 Then
Dim IncidentReport As New ListViewItem()
IncidentReport.Text = row(0) '
IncidentReport.SubItems.Add(row(1))
IncidentReport.SubItems.Add(row(2))
lstReports.Items.Add(IncidentReport)
End If
End While
End Using
In both cases, use Try/Catch rather than Dir() to check whether the location exists. Just try to open the file. Dir() costs an extra disk seek, and there are precious few things in programming slower than disk I/O.

Appending text files in a loop on array only prints 1 letter of first file

I have a folder C:\test\ that has multiple .txt files which I need to append to one output text file. Using FSO and TextStream I can write the files explicitly with no problem in this manner:
Public Sub test()
Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Const Path As String = "C:\test\"
Dim helloWorld As Object
Set helloWorld = FSO.CreateTextFile(FileName:=(Path & "helloworld.txt"), OverWrite:=True, Unicode:=False)
helloWorld.WriteLine FSO.GetFile("C:\test\Product_ID_update.txt").OpenAsTextStream(ForReading).ReadAll
helloWorld.WriteLine FSO.GetFile("C:\test\RPT-4475.txt").OpenAsTextStream(ForReading).ReadAll
helloWorld.Close
End Sub
It works perfectly, but I have hundreds of files to append so it would be crazy to type them all out, so I wrote some code to put all the file names into an array, then loop over each index to generate the file path. Here is the code:
Sub Combine_Text_Files2()
Dim InputDirPath As String
InputDirPath = "C:\test\"
Dim InputFileType As String
InputFileType = "*.txt"
Dim OutputDirPath As String
OutputDirPath = "C:\test\"
Dim OutputFileName As String
OutputFileName = "_CombinedOutput.txt"
Dim InputFileName As String
InputFileName = Dir$(InputDirPath & InputFileType)
Dim FileArray() As String
Dim i As Integer: i = 0
Do Until InputFileName = vbNullString
ReDim Preserve FileArray(0 To i)
FileArray(i) = InputFileName
InputFileName = Dir$
i = i + 1
Loop
Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim Stream As Object
Set Stream = FSO.CreateTextFile((OutputDirPath & OutputFileName), OverWrite:=True, Unicode:=False)
Dim FileNameAndPath As String
For i = LBound(FileArray) To UBound(FileArray)
FileNameAndPath = (InputDirPath & FileArray(i))
Debug.Print ("Processing: " & FileNameAndPath)
Dim fileToCopy As File
Set fileToCopy = FSO.GetFile(FileNameAndPath)
Dim streamToCopy As TextStream
Set streamToCopy = fileToCopy.OpenAsTextStream(ForReading)
Dim text As String
text = streamToCopy.ReadAll
Stream.WriteLine FSO.GetFile(FileNameAndPath).OpenAsTextStream(ForReading).ReadAll
Debug.Print ("Appended to " & OutputFileName & ": " & FileNameAndPath)
Next i
Stream.Close
End Sub
The FileNameAndPath value gets updated correctly, and as it goes through the first Stream.WriteLine iteration, it appends only the first letter of the first file to the output file, then moves on to the next iteration, and on the next Stream.WriteLine it fails due to Invalid procedure call or argument.
I've been trying to debug this for quite a while but not certain what is causing this. Only thing I can think of that might be causing it is the array, because it's really the only thing that is different AFAIK... Any help would be greatly appreciated!
Additional details
If I comment out the WriteLine call it goes through the entire array, printing all file paths to immediate. As you can see I broke down the original one-liner into multiple steps for debugging.
Replicating it is easy:
Create a C:\test\ directory
Create two or more text files and add text content to each of them
Run the code in the VBE
I found the problem. The problem was not the code, it works fine (though I feel sure could be improved, I'll take it over to Code Review).
The problem was that some of the source files were actually originally Excel documents that became converted to .txt and apparently carried over some meta-data that Notepad ignored, but the VBA compiler did not know what to do with trying to put it into a String.
Lesson learned, perform a sanity check of your source data.

How to display/save multiple (ADF) WIA images after scanned

I was tasked with creating a document digitizing program since the one the company bough borders on the awful. Its bad. Really bad. After some research I started a VB.NET WPF program. I already made login section and created the folders in a server where the files will be going, with the location of each file being saved in a SQL table. Anyway I basically need three things that are giving me a headache!
1) How to scan multiple pages with WIA? This is my current, and very raw scanning code:
Dim CD As New WIA.CommonDialog
Dim txt As String
Dim picture As Image
Dim F As WIA.ImageFile = CD.ShowAcquireImage(WIA.WiaDeviceType.ScannerDeviceType)
txt = txt1.Text
F.SaveFile("\\serverlocation" + txt + "." + F.FileExtension)
Txt is basically the name being given by the user. The problem is that this code only scans ONE page, how can I make it save multiple ones in the same file/separate files? (whichever works best).
In the same spirit of the previous question, is there a way to convert these files to JPEG/PNG (BMP takes a LOT of space) or even convert them to a PDF file if the user so wishes?
How do I display the scanned picture after its been scanned?
I am using VB.NET and WPF (not Forms). Any replies will be greatly appreciated :).
EDIT: Closest thing I've managed to multiple ADF scanning with http://forums.codeguru.com/showthread.php?439027-Windows-Image-Acquisition-%28WIA%29-Code . I converted C# to VB but the code throws me errors in the compiler.
Private Function scanMe(ByVal myDPI As Integer, ByVal myHeight As Double, ByVal myWidth As Double, ByVal ShowSelectScanner As Boolean, ByVal ShowScanPreview As Boolean) As Byte()
Dim CD As New WIA.CommonDialog
Dim device As WIA.Device = CD.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, ShowSelectScanner, False)
Dim item As WIA.Item = device.Items(1)
Try
With item
.Properties("Horizontal Resolution").Value = myDPI
.Properties("Vertical Resolution").Value = myDPI
.Properties("Horizontal Extent").Value = myDPI * myWidth
.Properties("Vertical Extent").Value = myDPI * myHeight
End With
Dim F As WIA.ImageFile
If ShowScanPreview Then
F = CD.ShowAcquireImage(WiaDeviceType.ScannerDeviceType, WiaImageIntent.ColorIntent, WiaImageBias.MaximizeQuality, WIA.FormatID.wiaFormatBMP, False, True, False)
Else
F = CD.ShowTransfer(item, WIA.FormatID.wiaFormatPNG, False)
End If
Dim myBuffer As Byte() = F.FileData.BinaryData
Return myBuffer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function

iTextSharp generating corrupted PDF in WPF

I am new to programming with iTextSharp. i have an application that writes in PDF file. File is written in word and than saved in PDF (there are 2 pages). My problem is, that when I want to write on PDF I see the data that was written on but the output PDF is corrupted. I don't understand why PDF gets corrupted?
Public Sub WriteForm(TemplateFilePath As String, NewFilePath As String, data As FormData)
'input output files
Dim oldFile As String = TemplateFilePath
Dim newFile As String = NewFilePath
'if file already exists then delete it
If System.IO.File.Exists(newFile) Then
System.IO.File.Delete(newFile)
End If
' open the reader
Dim reader As New PdfReader(oldFile)
Dim size As Rectangle = reader.GetPageSizeWithRotation(1)
Dim document As New Document(size)
' open the writer
Dim fs As New FileStream(newFile, FileMode.Create, FileAccess.Write)
Dim writer As PdfWriter = PdfWriter.GetInstance(document, fs)
document.Open()
'write data to first page
Me.WriteData(reader, writer, data)
'write second page
Me.AppendCopiedPage(document, writer, reader, 2)
' close the streams
document.Close()
fs.Close()
writer.Close()
reader.Close()
End Sub
'code for WriteData
Private Sub WriteData(reader As PdfReader, writer As PdfWriter, data As FormData)`
Dim cb As PdfContentByte = writer.DirectContent
Dim bf As BaseFont = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, BaseFont.EMBEDDED)
cb.SetColorFill(BaseColor.BLACK)
cb.SetFontAndSize(bf, 10)
' create the first page and add it to the pdf
Dim page1 As PdfImportedPage = writer.GetImportedPage(reader, 1)
cb.AddTemplate(page1, 0, 0)
Me.WriteText(cb, data.SID, 110, 653)
...
End Sub

Unzip a zip file in silverlight

I am trying to develop code to unzip file from the zip file in Silverlight 5. The files are in a directory within the zip file.
I translated this code I found elsewhere from c# to VB since we are a VB shop. It is failing on the fourth line "Object reference not set to an instance of an object.".
I realize now that the problem is that the third line is expecting a relative uri and I am passing it a file, but I don't know how to fix this.
Can you tell me what is wrong with this code. I will also welcome other ideas.
Thanks.
Public Shared Function GetZipContents(ByVal filename As String) As String()
Try
Dim zipStream As System.IO.Stream = New System.IO.MemoryStream()
Dim zipInfo As New StreamResourceInfo(zipStream, Nothing)
Dim streamInfo As StreamResourceInfo = Application.GetResourceStream(zipInfo, New Uri(filename, UriKind.Relative))
Dim fileStream As Stream = streamInfo.Stream
Dim names As New List(Of String)()
Dim reader As New BinaryReader(fileStream)
Do While reader.ReadUInt32() = &H4034B50
' Skip the portions of the header we don't care about
reader.BaseStream.Seek(14, SeekOrigin.Current)
Dim compressedSize As UInteger = reader.ReadUInt32()
Dim uncompressedSize As UInteger = reader.ReadUInt32()
Dim nameLength As Integer = reader.ReadUInt16()
Dim extraLength As Integer = reader.ReadUInt16()
Dim nameBytes() As Byte = reader.ReadBytes(nameLength)
names.Add(Encoding.UTF8.GetString(nameBytes, 0, nameLength))
reader.BaseStream.Seek(extraLength + compressedSize, SeekOrigin.Current)
Loop
' Move the stream back to the begining
fileStream.Seek(0, SeekOrigin.Begin)
Return names.ToArray()
Catch ex As Exception
MessageBox.Show(ex.Message)
Return Nothing
End Try
End Function
There is quick and dirty way to unzip in Silverlight.
Use Application.GetResourceStream Method.
http://msdn.microsoft.com/en-us/library/cc190632(v=vs.95).aspx
Check out my blogpost on this: http://www.sharpgis.net/post/2010/08/25/REALLY-small-unzip-utility-for-Silverlight-e28093-Part-2.aspx
Sorry I would have time to explore the suggestions. I did find a way to accomplish my goal on my own. See the code below. I would be using this code either because the Technical Leader here prefers I do it a different way using a WCF service. Warning I was not able to test this code 100% since I am not planning to use it, but it is close to being right.
Imports ICSharpCode.SharpZipLib.Zip
Public Shared Sub UnZip(ByVal SrcFile As String, ByVal DstFile As String, ByVal BufferSize As Integer)
Try
Dim _FileName As String
Dim _ZipEntry As ZipEntry
Dim _FileStreamOut As FileStream = Nothing
Dim _Done As Boolean = False
Dim _FileStreamIn As New FileStream(SrcFile, FileMode.Open, FileAccess.Read)
Dim _ZipInStream As New ZipInputStream(_FileStreamIn)
Do Until _Done = True
_ZipEntry = _ZipInStream.GetNextEntry()
If IsNothing(_ZipEntry) Then
_Done = True
Exit Do
End If
_FileName = DstFile & "\" & _ZipEntry.Name
_FileName = _FileName.Replace("/", "\")
If Right(_FileName, 1) = "\" Then
If Directory.Exists(_FileName) = False Then
Directory.CreateDirectory(_FileName)
End If
Else
_FileStreamOut = New FileStream(_FileName, FileMode.Create, FileAccess.Write)
Dim size As Integer
Dim buffer(BufferSize - 1) As Byte
Do
size = _ZipInStream.Read(buffer, 0, buffer.Length)
_FileStreamOut.Write(buffer, 0, size)
Loop While size > 0
End If
Loop
_ZipInStream.Close()
_FileStreamOut.Close()
_FileStreamIn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Resources