C#: Fehlermeldung NullReferenceException

Gast #3701110
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
    }
Gast #3701117
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
Gast #3701149
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.
#3701171
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
    }
Gast #3701172
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)
Gast #3701198
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
        }
#3701200
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.
Gast #3701205
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?
#3701208
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.
Gast #3701216
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
            }
#3701219
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren