Η μετονομασία του αρχείου δεν αλλάζει ούτε τα περιεχόμενα του ούτε τον τύπο του. Η παρέμβαση με PictureBox επίσης δεν κάνει τίποτε - το PictureBox δείχνει, δεν τροποποιεί. Εξάλλου, και το PictureBox από πίσω χρησιμοποιεί τις κλάσεις του GDI+ όπως Image και Bitmap. (Παρένθεση, αυτό μου θυμίζει κόλπα που κάναμε στην VB6, όταν δεν υπήρχαν κλάσεις και API για image manipulation, χμμμμμ ...)
Τί ακριβώς μήνυμα σου βγάζει το Photoshop? Μπορείς να ανοίξεις το αρχείο σε κάποιο άλλο viewer ή πρόγραμμα, όπως π.χ. το Paint.NET? Μπορεί το ... ε ...
....
Και η κατάληξη του αρχείου πάω στοίχημα ότι είναι κομμένη. Αν δεις το link που σου έστειλα, τα JPEG/JFIF αρχεία ξεκινάνε με FF D8 FF E0 xx xx 4A 46 49 46 00 ( ÿØÿà..JFIF. σε ASCII) και τελειώνουν με FF D9 (ÿÙ).
Ο κώδικας σου όμως, ΚΟΒΕΙ το τελευταίο byte γιατί αντί να δώσεις count στην Write, δίνεις το upper bound του MyData, που είναι ίσο με το MyData.Length -1.
Γενικά, ο κώδικας θέλει μάζεμα γιατί αφήνει πολλά πράγματα στην τύχη. Καταρχήν, αν συμβεί το παραμικρό λάθος θα μείνουν αρχεία και η σύνδεση στη βάση ανοικτά, καθώς δεν θα εκτελεστούν ποτέ οι Close του reader και του stream. Θα πρέπει να χρησιμοποιήσεις το Using για να εξασφαλίσεις ότι θα κλείσουν ακόμα και αν υπάρξει σφάλμα, π.χ. επειδή κάποιο αρχείο υπήρχε ή ήταν ήδη ανοικτό.
Δεύτερον, ορίζεις μεταβλητές έξω από το loop οι οποίες όμως χρησιμοποιούνται μόνο μέσα στο loop. Αυτό σημαίνει ότι θα διατηρήσουν τις τιμές τους ακόμα και όταν τελειώσει το loop. Αυτό μπορεί να είναι πολύ κακό στην περίπτωση του MyData, το οποίο μπορεί να περιέχει κάποια megabytes δεδομένων.
Θα έπρεπε δηλαδή να γράψεις κάτι σαν αυτό:
'SAVE BLOB AS IMAGE
sql = "SELECT ItemGID,ItemCode,ImageBlobData" _
& " FROM Items" _
& " WHERE ImageBlobData is not null"
Using thisCommand As New SqlCommand(sql, cnSource)
Using thisReader As SqlDataReader = thisCommand.ExecuteReader()
While (thisReader.Read())
Dim MyData() As Byte = thisReader(2)
Dim file_name As String = GET_IMAGE_FOLDER & thisReader(1) & "." & GET_IMAGE_TYPE
Using fs As New FileStream(file_name, FileMode.Create)
fs.Write(MyData, 0, MyData.Length)
fs.Close()
End Using
End While
End Using
End Using
Το τρίτο θέμα, είναι ότι τα BLOBs συνήθως είναι μεγάλα και ο κώδικας σου τα φορτώνει όλα μαζί με τη μία στη μνήμη. Αντί γι αυτό, μπορείς να τα διαβάσεις τμηματικά, όπως περιγράφεται στο
Retrieving Large Data (ADO.NET) . Πρόσεχε όμως το sample, γιατί ούτε εκεί χρησιμοποιείται το Using και θα υπάρχουν τα ίδια θέματα αν το χρησιμοποιήσεις όπως είναι.
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos