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
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.
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....
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???
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();
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:
Grüße Schuppsl
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
- 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).
- 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.
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.
Klar, in diesem Beispiel macht das Umwandeln in einen String natürlich keinen Sinn.
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. 😉
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🙂
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.
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 🙂
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