Laden...

mehrere Bilder in einem BLOB speichern

Erstellt von scoda vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.544 Views
S
scoda Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren
mehrere Bilder in einem BLOB speichern

Hallo zusammen,

ich möchte 100 Bilder, die auf der Festplatte liegen, in einen BLOB im SQL Server 2005 abspeichern und anschließend aus der Datenbank wieder auslesen und auf Festplatte speichern.

Ich habe folgenden Ansatz:

private void SaveAllImagesToOneBlob()
        {
            string[] s = new string[listBox1.Items.Count];
            byte[] data = null;

            for (int i = 0; i < listBox1.Items.Count; i ++)
            {
                FileInfo fi = new FileInfo(listBox1.Items[i].ToString());
                long numBytes = fi.Length;
               
                FileStream fs = new FileStream(fi.ToString(), FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                data = br.ReadBytes((int)fi.Length);
       
                //---- BLOB erzeugen -----
                FileStream fstream = new FileStream("D:\\blob.dat", FileMode.Append, FileAccess.Write);
                BinaryWriter bw = new BinaryWriter(fstream);
                
                bw.Write(numBytes);
                bw.Write(data);
                bw.Close();
                fstream.Close();
                //--------------------------------
            }
        }

Ich muss irgendwie kennzeichnen wo das nächste Bild im BLOB anfängt.
Also brauche ich einen Header, der die Größe des nächsten Bildes enthält.
Aber wie kann man das am besten realisieren?

Gruß
scoda

U
237 Beiträge seit 2007
vor 14 Jahren

Warum nicht lieber eine extra Tabelle für die Bilder?

heute code ich, morgen debug ich und übermorgen cast ich die königin auf int

S
scoda Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren

Warum nicht lieber eine extra Tabelle für die Bilder?

Ich benutze doch eine extra Tabelle:

CREATE TABLE [dbo].[pics](
[picid] [int] IDENTITY(1,1) NOT NULL,
[name] nvarchar COLLATE Latin1_General_CI_AS NULL,
[path] nvarchar COLLATE Latin1_General_CI_AS NULL,

M
334 Beiträge seit 2007
vor 14 Jahren

[data] [image] NULL, CONSTRAINT [PK_tbl_pics] PRIMARY KEY CLUSTERED

ähh seh ich das richtig? ein PK-Index auf einem BLOB-Feld?

zu deiner Frage, ich seh da 2 mögliche Lösungen:

  1. Eigene Serialisierung schreiben
  2. Ein Bild pro Datensatz und über eine zweite Tabelle die "Gruppen" (oder was auch immer die 100 Bilder sein sollen) abbilden.
S
scoda Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren

[data] [image] NULL, CONSTRAINT [PK_tbl_pics] PRIMARY KEY CLUSTERED

ähh seh ich das richtig? ein PK-Index auf einem BLOB-Feld?

zu deiner Frage, ich seh da 2 mögliche Lösungen:

  1. Eigene Serialisierung schreiben
  2. Ein Bild pro Datensatz und über eine zweite Tabelle die "Gruppen" (oder was auch immer die 100 Bilder sein sollen) abbilden.
  • Nein, picid ist der PK.

  • Was bringt mit denn die Serialisierung?

  • Soll ja eben NICHT ein Bild pro Datensatz sein (das habe ich schon), sondern alle Bilder in einen Datensatz gehen.

Ich bin mittlerweile weiter gekommen.
Ich schreibe vor jedes Bild einen Header von 32 Bit, in dem die Information über die Größe des Bildes steht.
Anschließend benutze ich die Read()-Methode des BinaryReaders zum auslesen des Bildes aus dem BLOB. Der Read()-Methode kann übergeben werden wieviel sie lesen soll.

Gruß
scoda

S
248 Beiträge seit 2008
vor 14 Jahren

Hallo scoda,

ich würde den Blob so aufbauen:

[Länge der Bilddaten][Bilddaten][Länge der Bilddaten][Bilddaten][Länge der Bilddaten][Bilddaten]

So kannst du einfach Bilder anfügen oder durch die Datei zum x-ten Bild springen.

Spooky

S
scoda Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren

Hallo scoda,

ich würde den Blob so aufbauen:

[Länge der Bilddaten][Bilddaten][Länge der Bilddaten][Bilddaten][Länge der Bilddaten][Bilddaten]

So kannst du einfach Bilder anfügen oder durch die Datei zum x-ten Bild springen.

Spooky

Hallo Spooky,

genau so hatte ich mir die Theorie auch überlegt.
Nur ich wusste nicht, wie ich dies in der Praxis umsetzen soll.
Jetzt kenne ich die Methode vom BinaryReader: ReadInt16() und Read() usw.

Danke für alle Antworten.

Viele Grüße
scoda

1.564 Beiträge seit 2007
vor 14 Jahren

Hallo scoda

Warum willst du den alle Bilder in einen BLOB zusammenfügen? Du erfindest damit doch nur Probleme mit denen man sich später rumschlagen muss. Warum nicht eine eigene Tabelle und eine 1:n Relation?

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

M
334 Beiträge seit 2007
vor 14 Jahren
  • Nein, picid ist der PK.

  • Was bringt mit denn die Serialisierung?

  • Soll ja eben NICHT ein Bild pro Datensatz sein (das habe ich schon), sondern alle Bilder in einen Datensatz gehen.

Ah ich hab das Komma übersehen, alles klar. 🙂

Mit Serialisierung meinte ich im Prinzip das was Spook auch geschrieben hat.

Aber nur zum Verständnis, warum die ganze Mühe? Wir versuchen nur dem ganzen einen Sinn zu geben. 😉

S
scoda Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren
  • Nein, picid ist der PK.

  • Was bringt mit denn die Serialisierung?

  • Soll ja eben NICHT ein Bild pro Datensatz sein (das habe ich schon), sondern alle Bilder in einen Datensatz gehen.

Ah ich hab das Komma übersehen, alles klar. 😃

Mit Serialisierung meinte ich im Prinzip das was Spook auch geschrieben hat.

Aber nur zum Verständnis, warum die ganze Mühe? Wir versuchen nur dem ganzen einen Sinn zu geben. 😉

Warum die ganze Mühe?
Okay, dann kläre ich euch auf.

Ich habe mehrere Testszenarien für einen Performance Test geschrieben.
Einer dieser Tests ist das Abspeichern von Bildern in einen Blob.
Wobei ich die Lese- und Schreibgeschwindigkeit ermitteln will und anschließend vergleiche.

Für den performantesten Weg entscheide ich mich dann.

Viele Grüße
scoda

1.564 Beiträge seit 2007
vor 14 Jahren

Also willst du nicht wirklich Bilder zusammengehängt in die Datenbank schreiben sondern brauchst einfach nur irgendeine große Binärdatei.

Ein paar kleine Hints:
* Wenn alles auf einmal geschrieben werden kann (weil's der RAM vom Server und Client hergeben) ist natürlich ein einzelner INSERT oder ein einzelnes UPDATE am schnellsten
* Wenn in Teilstücken schreiben willst/musst ist das - mit Abstand - schnellste die WRITE Methode von VARCHAR(MAX)/VARBINARY(MAX) bei der du das Offset angeben kannst.
* Wenn komplett lesen willst/kannst, einfacher SELECT
* Wenn du in Teilstücken lesen willst/musst, einfach SUBSTRING (geht auf für VARBINARY)
* Um die Menge der Roundtrips übers Netzwerk zu minimieren kannst du im ConnectionString die "Packet Size" anpassen siehe SqlConnection.ConnectionString Property und SqlConnection.PacketSize Property

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

S
scoda Themenstarter:in
41 Beiträge seit 2009
vor 14 Jahren

Also willst du nicht wirklich Bilder zusammengehängt in die Datenbank schreiben sondern brauchst einfach nur irgendeine große Binärdatei.

Ein paar kleine Hints:
* Wenn alles auf einmal geschrieben werden kann (weil's der RAM vom Server und Client hergeben) ist natürlich ein einzelner INSERT oder ein einzelnes UPDATE am schnellsten
* Wenn in Teilstücken schreiben willst/musst ist das - mit Abstand - schnellste die WRITE Methode von VARCHAR(MAX)/VARBINARY(MAX) bei der du das Offset angeben kannst.
* Wenn komplett lesen willst/kannst, einfacher SELECT
* Wenn du in Teilstücken lesen willst/musst, einfach SUBSTRING (geht auf für VARBINARY)
* Um die Menge der Roundtrips übers Netzwerk zu minimieren kannst du im ConnectionString die "Packet Size" anpassen siehe
>
und
>

Danke dir!
Werde die Sachen berücksichtigen.

Viele Grüße
scoda