Forum: PC-Programmierung C#: Fehlermeldung NullReferenceException


von csharp_user (Gast)


Lesenswert?

Guten Morgen,

wie kann in einer anderen Methode auf das Objekt imageStream zugeriffen 
werden? Nach Ausführung der Buttonmethode btn_Load_Click soll der Button 
btn_SendImage_Click ausgeführt werden. Bei der folgenden Zeile,
1
while ((bytesSize = imageStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
 zeigt Visual Studio einen Fehler an. Es handelt sich hierbei um einen 
NullReferenceException Fehler. Was könnte ich tun, damit ich auch in der 
Methode btn_SendImage_Click auf das Objekt imageStream zugreifen kann?

1
public partial class FormSendImage : Form
2
    {
3
        FileStream imageStream;
4
5
        public FormSendImage()
6
        {
7
            InitializeComponent();
8
        }
9
10
        public void btn_SendImage_Click(object sender, EventArgs e)
11
        {
12
            int bytesSize = 0;
13
            byte[] downBuffer = new byte[32 - 2];
14
            byte[] sendBuffer = new byte[32];
15
16
17
            int chunkNumber = 0;
18
            while ((bytesSize = imageStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
19
            {
20
21
            }
22
23
            imageStream.Close();
24
        }
25
26
        public void btn_Load_Click(object sender, EventArgs e)
27
        {
28
            if (ImageOpenFileDialog.ShowDialog() == DialogResult.OK)
29
            {
30
                using (FileStream imageStream = new FileStream(ImageOpenFileDialog.FileName, FileMode.Open, FileAccess.Read))
31
                {
32
33
                }
34
            }
35
        }
36
    }

von JensM (Gast)


Lesenswert?

Der Zugriff auf imageStream ist in der Funktion möglich.
Alles korrekt.

Das Objekt imageStream ist noch null (NullReferenceException).

Es muss irgendwo vor dem ersten Zugriff ein Objekt erzeugt werden.

z.B.
imageStream = new FileStream();

Gruß JensM

von Borislav B. (boris_b)


Lesenswert?

Dir ist schon klar, dass du zwei imageStreams hast?
Und nur einer davon wird initialisiert (aber auch gleich darauf wieder 
abgeräumt).

csharp_user schrieb:
> FileStream imageStream;

csharp_user schrieb:
> using (FileStream imageStream = new FileStream...

von csharp_user (Gast)


Lesenswert?

Ich möchte zuerst das Bild in ein FileStream laden. Im Anschluss möchte 
ich mit der anderen Funktion btn_SendImage_Click auf den gleichen 
FileStream zugreifen können, ohne das die Fehlermeldung erscheint.

von csharp_user (Gast)


Angehängte Dateien:

Lesenswert?

>Dir ist schon klar, dass du zwei imageStreams hast?
>Und nur einer davon wird initialisiert (aber auch gleich darauf wieder
>abgeräumt).

Habe ich bereits berichtigt.

Trotzdem erscheint nun eine andere Fehlermeldung: sieh Anhang

von Borislav B. (boris_b)


Lesenswert?

Wie sieht dein Code denn jetzt aus? Verwendest du immernoch das using?
Das macht deinen Stream natürlich dicht. Wenn du den also weiter 
verwenden willst, solltest du das using entfernen.

von Lenny D. (le-do)


Lesenswert?

Hm Boris hat Recht, du hast 2 mal die Deklaration "FileStream 
imageStream" mit gleichem Namen, komisch dass das überhaupt kompiliert.
Eine using-Direktive begrenzt den Scope einer Variablen, d.h. am Ende 
des using Blocks wird der Stream wieder deinitialisiert (weil du ihm ja 
sagst ich brauche ihn nur innerhalb des Bereichs).

Wenn das using keinen guten Grund hat machs wieder weg (dann musst du 
aber selbst später den Stream wieder schließen, ich denke mit .Close() 
oder .Dispose() oder so, schau mal im Internet), außerdem reicht da dann 
imageStream ohne "FileStream" davor, das steht ja schon global einmal.

Dann müsstest du nach dem Laden von überall Zugriff auf ImageStream 
haben.
Allerdings sollte in dem Send Button trotzdem nochmal auf !=null 
checken, da er unter Umständen ja vor dem Laden gedrükt wird (selbst 
wenn du ihn vorher ausgraust oder so ist es kein guter Stil so einen 
Fallstrick offen zu lassen). Hier also eine kleine Verbesserung:

1
public partial class FormSendImage : Form
2
    {
3
        FileStream imageStream;
4
5
        public FormSendImage()
6
        {
7
            InitializeComponent();
8
        }
9
10
        public void btn_SendImage_Click(object sender, EventArgs e)
11
        {
12
            if(imageStream == null)
13
                return; //sollte sowieso nich passieren, aber hier checken so kommt wenigstens keine Exception
14
            int bytesSize = 0;
15
            byte[] downBuffer = new byte[32 - 2];
16
            byte[] sendBuffer = new byte[32];
17
18
19
            int chunkNumber = 0;
20
            while ((bytesSize = imageStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
21
            {
22
                //hier passiert was, schreib das immer dazu wenn du code löscht zum posten
23
            }
24
25
            imageStream.Close();
26
        }
27
28
        public void btn_Load_Click(object sender, EventArgs e)
29
        {
30
            if (ImageOpenFileDialog.ShowDialog() == DialogResult.OK)
31
            {
32
                imageStream = new FileStream(ImageOpenFileDialog.FileName, FileMode.Open, FileAccess.Read)
33
            }
34
        }
35
36
        //TODO: OnFormClose oder so spätestens den Stream schließen mit .Dispose o.Ä.
37
    }

von csharp_user (Gast)


Lesenswert?

using habe ich nun entfernt:

[/c]
if (ImageOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                imageStream = new 
FileStream(ImageOpenFileDialog.FileName, FileMode.Open, 
FileAccess.Read);
}
[/c]

Allerdings ist byteSize in der while Schleife immer null:
1
while ((bytesSize = imageStream.Read(downBuffer, 0, downBuffer.Length)) > 0)

von csharp_user (Gast)


Lesenswert?

Wenn ich das Bild in der Methode btn_SendImage öffne, dann wird die 
while Schleife korrekt ausgeführt.
1
        public void btn_SendImage_Click(object sender, EventArgs e)
2
        {
3
            string filePath = @"C:\Test\";
4
            string fileName = "Image.jpg";
5
6
            imageStream = new FileStream(filePath + fileName, FileMode.Open, FileAccess.Read);
7
8
            if(imageStream == null)
9
                return; //sollte sowieso nich passieren, aber hier checken so kommt wenigstens keine Exception
10
            int bytesSize = 0;
11
            byte[] downBuffer = new byte[32 - 2];
12
            byte[] sendBuffer = new byte[32];
13
14
15
            int chunkNumber = 0;
16
            while ((bytesSize = imageStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
17
            {
18
                //hier passiert was, schreib das immer dazu wenn du code löscht zum posten
19
            }
20
21
            imageStream.Close();
22
        }

von Borislav B. (boris_b)


Lesenswert?

csharp_user schrieb:
> Wenn ich das Bild in der Methode btn_SendImage öffne, dann wird die
> while Schleife korrekt ausgeführt.

Das sollte keinen Unterschied machen.

Frage: machst du vorher schon etwas mit dem Stream? Also NACHDEM du ihn 
geöffnet hast und BEVOR du btn_SendImage_Click aufrufst?
Falls du z.B. schon daraus gelesen hast, kannst du das nicht ohne 
Weiteres noch ein zweites mal tun.

von csharp_user (Gast)


Lesenswert?

Ja. Auf der Oberfläche wird die Byte Größe des Bildes und das Bild 
ausgegeben. Was kann ich da tun, damit ich trotzdem in der Methode 
btn_Load_Click die Bytegröße sowie das Bild ausgeben kann?

von Borislav B. (boris_b)


Lesenswert?

csharp_user schrieb:
> Ja. Auf der Oberfläche wird die Byte Größe des Bildes und das Bild
> ausgegeben. Was kann ich da tun, damit ich trotzdem in der Methode
> btn_Load_Click die Bytegröße sowie das Bild ausgeben kann?

Warum willst du denn den FileStream wiederverwenden? Ich glaube das ist 
nicht sinnvoll...

Öffne doch einfach immer einen neuen Filestream an den Stellen, wo du 
ihn benötigst. Dann kannst du dort auch immer das using verwenden, was 
dir ein sauberes Aufräumen garantiert.

von csharp_user (Gast)


Lesenswert?

1
            if (ImageOpenFileDialog.ShowDialog() == DialogResult.OK)
2
            {
3
                imageStream = new FileStream(ImageOpenFileDialog.FileName, FileMode.Open, FileAccess.Read);
4
5
                lbl_Size.Text = "Picture size [bytes]: " + imageStream .Length.ToString();
6
                    
7
                pictureBox.Image = System.Drawing.Image.FromStrea(imageStream);
8
            }

von Lenny D. (le-do)


Lesenswert?

Ein Stream geht Zeichen für Zeichen durch die Quelle und schreibt diese 
in seinen (größenbegrenzten) Buffer den du dann stückweise oder komplett 
liest. Bei jedem gelesenen Zeichen geht er daher natürlich eins weiter. 
Wenn du das Bild einmal ausliest bist du am Ende des Streams angekommen, 
da folgen keine weiteren Daten.
Mit Stream.Seek kannst du an den Anfang (oder andere Positionen) des 
Streams zurückspringen.
http://msdn.microsoft.com/de-de/library/system.io.filestream.seek%28v=vs.110%29.aspx

Ansonsten sind Boris' Alternativen auch gut.

von csharp_user (Gast)


Lesenswert?

Verwende nun die Methode Seek. Nun funktioniert es so wie ich es möchte.

Vielen vielen Dank!

von Borislav B. (boris_b)


Lesenswert?

Vergiss aber nicht, den Stream zu disposen!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.