Laden...

Was ist hier falsch?Lesen und schreiben in Datei

Erstellt von schuppsl vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.086 Views
S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 16 Jahren
Was ist hier falsch?Lesen und schreiben in Datei

Hallole. Ich übe mich gerade in C#.
Ich lese Asynchron aus einer Datei und schreibe es in eine andere.
Es hat schonmal funktioniert, jetzt aber nicht mehr.
Die Datei wird zwar erstellt, aber es wird nichts reingeschrieben.



using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net.Sockets;
using System.Collections;
using System.Windows.Forms;

//Eigene
using Kommunikation;

namespace AsynchronousIO
{
    class AsynchIOTester
    {
        private Stream inputStream;
        private Stream outputStream;

        private AsyncCallback myCallback;

        private byte[] buffer;

        const int BufferSize = 1024;

        AsynchIOTester()
        {
            //file öffnen

            buffer = new byte[ BufferSize ];

            myCallback = new AsyncCallback( this.OnCompletedRead );

            try
            {
                inputStream = File.OpenRead(@"c:\wwwisapilog_SEND.log");
            }
            catch (IOException e)
            {
                MessageBox.Show("Fehler; {0}",e.ToString());
            }

        }

        public static void Main()
        {

            AsynchIOTester theApp = new AsynchIOTester();
            theApp.Run();
        }

        void Run()
        {

            inputStream.BeginRead(buffer, 0, buffer.Length, myCallback, null);


        }

        void OnCompletedRead(IAsyncResult asyncResult)
        {

            int bytesRead = inputStream.EndRead( asyncResult );
            
            if (bytesRead > 0)
            {
                string s = Encoding.ASCII.GetString(buffer, 0, bytesRead);
               
              try{
                FileStream fs = new FileStream(@"c:\KOPIE.log",FileMode.Append);
                StreamWriter sw = new StreamWriter(fs);
                sw.Write(s);

              }catch (IOException e)
              {
                  MessageBox.Show("Fehler: {0}",e.ToString() );
              }
                                
                inputStream.BeginRead(buffer, 0, buffer.Length, myCallback, null);
             

            }


        }


    }
}





Ich denke das wichtigeste ist in der Funktion void OnCompletedRead.
wenn ich debugge, dann läuft er bis StreamWriter fs...aber zum schreiben kommt er nicht mehr.

Warum das?

Danke für die Hilfe...

EDIT: Es muss irgendwie an s liegen.
Wenn ich direkt nach try.. MessageBox.Show(s); schreibe bricht er da ab uns zeigt die MessageBox nicht an.

Habs mal mit
string s = System.Text.Encoding.Default.GetString(buffer);

versucht..geht auch nicht...

EDIT2:
Es liegt an was anderem.
Wenn ich MessageBox.Show("Hallo");
schreibe bricht er da ab...die Messagebox wird nicht angezeigt
Hängt das mit der Callback funktion zusammen?
wenn ich die Messagebox in Run() reinschiebe, gehts....
Verwende Visual Studio 2008

6.862 Beiträge seit 2003
vor 16 Jahren

Also ein großes Problem was du hast ist schonmal das fehlende schließen der Streams. Bei kleinen Datenmengen bleibt alles im Puffer und dein Programm schließt ohne die Daten wirklich auf Platte zu schreiben und dann ist kein Wunder wenn nichts drin ist 🙂

Baka wa shinanakya naoranai.

Mein XING Profil.

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 16 Jahren

Ja ok. Aber selbst wenn ich sw.Flush() schreibe, wird nicht geschrieben.
Es muss igendein Problem mit der Callbackfunktin geben...
Selbst wenn ich da ganz am Anfang eine Messagebox.Show("Hello"); schreibe, wird diese nicht angezeigt.
Weiter oben im Code aber schon....

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 16 Jahren

Wenn ich das als Bytes schreibe funktionierts:



 FileStream fs = new FileStream(@"c:\wwwisapilog_SENDKOPIE.log",FileMode.Append );
                fs.Write(buffer, 0, buffer.Length);
                  
                fs.Flush();
                      fs.Close();

Nur halt immer vom Anfang.
Warum geht es mit bytes und warum gehts mit nem String nicht???

50 Beiträge seit 2006
vor 16 Jahren

Hallo,

also Dein Hauptproblem liegt schon mal in der Methode Main.


AsynchIOTester theApp = new AsynchIOTester();
theApp.Run();

Da deine Leseoperation asynchron aufgerufen wird, verlässt er zu einem unbestimmten Zeitpunkt die Methode Main. Zu diesem Zeitpunkt wurde die Datei evtl. noch gar nicht komplett gelesen. Du musst also dafür sorgen, dass das Programm sich nicht selbstständig beendet.

Damit er die Main-Methode nicht verlässt, habe ich Testweise einfach mal einen Console.ReadKey() eingebaut.


AsynchIOTester theApp = new AsynchIOTester();
theApp.Run();
Console.ReadKey();

Desweiteren solltest Du in der Callback-Funktion auf jeden Fall nach dem du den string geschrieben hast, die Datei wieder schließen.


sw.Close();

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 16 Jahren

Stream schließen, ok ist klar.

Und es war tatsächlich das Problem, daß die Anwendung beendet wurde, bevor der Stream geschrieben werden konnte->Asynchron.

Im Buch macht der da ne for-Schleife mt zigtausend durchläufen.
Das habe ich großzügig übersprungen 🙂
Jetzt weiß ich warum.
Vielen Dank für die Hilfe, hab was dazugelernt.

Dabei hätte ich noch ein paar Fragen:

  1. Wird für die Callbackfunktion ein Thread erstellt?
  2. Was ist genau der Unterschied wenn ich das als byte oder String in die Datei schreibe?
    Es steht in beiden Fällen dasselbe drin.

Grüße Schuppsl

50 Beiträge seit 2006
vor 16 Jahren

Bitte gerne geschehen. Ist vielleicht auch nicht so das richtige Beispiel für eine asynchrone Operation. Aber zum Üben kann man es verwenden 😉

Gruß Björn

S
8.746 Beiträge seit 2005
vor 16 Jahren
  1. Wird für die Callbackfunktion ein Thread erstellt?

Nein, der Callback wird direkt aus dem Thread ausgelöst, aus dem auch die asychrone Operation läuft. Das ist ein Thread aus dem Pool, wird also nicht extra erzeugt (das wäre zu langsam).

  1. Was ist genau der Unterschied wenn ich das als byte oder String in die Datei schreibe? Es steht in beiden Fällen dasselbe drin.

Wenn du Bytes schreibst. musst du zuvor den String per Hand encodieren.

50 Beiträge seit 2006
vor 16 Jahren

Wenn du Bytes schreibst. musst du zuvor den String per Hand encodieren.

Nicht ganz. Da er ja sowieso in seinem StreamReader ein Byte-Array zurück bekommt, könnte er auch dieses direkt schreiben.

S
8.746 Beiträge seit 2005
vor 16 Jahren

Klar, in diesem Beispiel macht das Umwandeln in einen String natürlich keinen Sinn.

50 Beiträge seit 2006
vor 16 Jahren

Die Frage kann man sowieso nicht pauschal beantworten. Kommt tatsächlich immer auf den spezifischen Anwendungsfall an. Wenn man den nicht kennt, ist es schwer die korrekte Antwort zu geben. Sein Beispiel hätte man auch ganz einfach mit der File.Copy(...,...) Methode lösen können. 😉

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 16 Jahren

Sein Beispiel hätte man auch ganz einfach mit der File.Copy(...,...) Methode lösen können. 😉

Schon klar. Aber ich will ja Asynchrones Streaming üben🙂

50 Beiträge seit 2006
vor 16 Jahren

Ist mir schon klar. Wollte nur damit sagen, dass man gewisse Fragen eben nicht immer eindeutig beantworten kann. Da kommt es dann eben auf den Anwendungsfall an.

Es ging ja um die Frage wo der Unterschied beim Schreiben von Byte oder String liegt. In Deinem Fall gibt es da keinen Unterschied. Wenn Du aber eben als Input Binärdateien hättest, dann könntest Du diese nicht so einfach als String speichern.

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 16 Jahren

Hm...das ist eingentlich klar, ich komme aus der C/C++ Ecke.
habe noch so meine Probleme mit dem verkapselten, Überladenen, Gemanagten Zeugs🙂

Ich verstehe nicht, warum der FileStream nur binäre Daten liest/Schreibt und ich , wollte ich mit Strings arbeiter dafür einen Streamwriter erzeugen muss.
Aber das ist wohl einfach so 🙂

50 Beiträge seit 2006
vor 16 Jahren

Nunja, das ist halt wirklich einfach so. Die Klassen die Du dort ansprichst sind alles Klassen, die von der Basisklasse Stream erben. Jede dieser Klassen ist eben für einen speziellen Fall vorgesehen. Die Klasse FileStream liefert eben ein ByteArray.

Man muss dann eben entscheiden, was ist mein Ursprung und was brauche ich und wie sollen die Daten verarbeitet werden