WinFuture-Forum.de: Synchrones Filecopy - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
  • 2 Seiten +
  • 1
  • 2

Synchrones Filecopy C# und .NET 1.1 SP1


#1 Mitglied ist offline   DonElTomato 

  • Gruppe: aktive Mitglieder
  • Beiträge: 311
  • Beigetreten: 04. Oktober 05
  • Reputation: 0

geschrieben 28. April 2006 - 09:09

Hallo,

ich möchte gerne eine Datei kopieren allerdings gibt es da ein Problem:

Wenn ich folgenden Code ausführe...

File.Copy(@"C:\TEST.exe",@"D:\TEST.exe");
MessageBox.Show("Fertig!","Hinweis");

... wird die Datei zwar kopiert, aber da sie etwas größer ist fällt sehr stark auf das der MessageBox-Befehl schon ausgeführt wird, wenn die Datei noch garnicht vollständig kopiert wurde !?

Im Netz bin ich darauf gestoßen das beide Prozesse (also Origramm und File.Copy sind Synchron zueinander laufen. Ich müsste sie irgendwie dazu bringen dies zu tun, aber die Quelltexte im Netz sind so unverständlich das ich nimmer weiter weiss.

Könnt ihr mir was hilfreiches Mitteilen?

MFG

Don
0

Anzeige



#2 Mitglied ist offline   MNG 

  • Gruppe: aktive Mitglieder
  • Beiträge: 293
  • Beigetreten: 29. März 06
  • Reputation: 0

  geschrieben 28. April 2006 - 09:27

Moin,

also, primitiv aber wirksam wäre

File.Copy(@"C:\TEST.exe",@"D:\TEST.exe");

FileStream fs = new FileStream("D:\TEST.exe", FileMode.Open);
while(!fs.CanWrite)
	 //tue gar nichts
fs.close();

MessageBox.Show("Fertig!","Hinweis");


Das solte deinen Haupt-Thread solange blockieren, bis die Zieldatei komplett geschrieben wurde.
Eleganter (aber aufwendiger) wäre es sicherlich, mit snchronisierten Threads zu arbeiten und die Zieldatei zu "locken".... das ergibt aber einen Haufen Zeilen an Mehr-Code.
0

#3 Mitglied ist offline   DonElTomato 

  • Gruppe: aktive Mitglieder
  • Beiträge: 311
  • Beigetreten: 04. Oktober 05
  • Reputation: 0

geschrieben 28. April 2006 - 09:50

Gute Idee, aber leider funktioniert das nicht!? Kann es eventuell damit zusammenhängen das dass ganze in einem Windows-Service gschieht?
0

#4 Mitglied ist offline   Lofote 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.526
  • Beigetreten: 24. August 04
  • Reputation: 1

geschrieben 28. April 2006 - 10:17

Der Code von MNG kann nicht tun, weil der While-Teil sofort ausgeführt wird. Wenn dann so:

FileStream fs = new FileStream("D:\TEST.exe", FileMode.Open);
while(!fs.CanWrite)
{
	 //tue gar nichts
}
fs.close();


Trotzdem ist es Murx, denn: Wer sagt, dass zu dem Zeitpunkt der FileCopy-Prozess schon begonnen hat (bei sehr schnellen Multi-CPU-Geräten kann das sein, dass das asynchron erst später gestartet wird. Ausserdem ist die CPU-Auslastung glaub ich auch nicht 0 bei der while-Schleife.

Was ich nicht verstehe: ich habe das gerade selbst probiert, und bei mir wartet File.Copy(). Das sollte es auch, weil sonst würde was in der Hilfe stehen. Bist du sicher, dass dein Explorer (oder was auch immer du für die ANzeige des Verzeichnisses zum Prüfen, obs fertig ist, verwendest) vielleicht nur noch nicht die Anzeige aktualisiert hat?

Ach ja: EIn WIndows-Dienst, der direkt über den Desktop mit dem Benutzer kommunizieren kann, ist ne riesen Sicherheitslücke, bist du sicher, dass du dem User über nen Dienst ne MessageBox zeigen willst?
0

#5 Mitglied ist offline   DonElTomato 

  • Gruppe: aktive Mitglieder
  • Beiträge: 311
  • Beigetreten: 04. Oktober 05
  • Reputation: 0

geschrieben 28. April 2006 - 10:23

Der Dienst ist ein Windows-Diest unter dem Lokalen Systemkonto. Dieser schreibt seine Statusinformationen in eine XMl-Datei die von meinem Programm ausgelsen wird. das geschieht alle x Milli-Sekunden. Wurde die Datei fertig kopiert steht dort was entsprechendes drin, aber das steht nach nicht mal 1 Sekunde dort drin. Und die Datei ist 400MB Groß. Also ist entweder mein Rechner für übermorgen (ich glaubs kaum) oder da läuft irgendwas nicht so ganz mit rechten Dingen zu.

Seltsam ist auch, dass alles richtig klappt wenn ich ein Windowsform mit Button nehme und dort den selben Code ausführe. Dann klappt alles so, wie es soll.

Ich blick da irgendwie nich durch...
0

#6 Mitglied ist offline   Lofote 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.526
  • Beigetreten: 24. August 04
  • Reputation: 1

geschrieben 28. April 2006 - 10:44

Hm, mag ne blöde Frage sein, aber manchmal sinds die Kleinigkeiten :(... haste mal gecheckt, ob der Kopiervorgang funktioniert hat? Also wird die Datei überhaupt kopiert?
0

#7 Mitglied ist offline   DonElTomato 

  • Gruppe: aktive Mitglieder
  • Beiträge: 311
  • Beigetreten: 04. Oktober 05
  • Reputation: 0

geschrieben 28. April 2006 - 10:47

Jepp kopiert wird sie. Und wenn die MessageBox kam höre ich trotzdem die Festplatte wie sie rödelt und rödelt. Aber löschen kann ich die Datei erst 20Sekunden später da "Sie von einem anderen Prozess verwendet wird"
0

#8 Mitglied ist offline   MNG 

  • Gruppe: aktive Mitglieder
  • Beiträge: 293
  • Beigetreten: 29. März 06
  • Reputation: 0

geschrieben 28. April 2006 - 11:07

Zitat

Der Code von MNG kann nicht tun, weil der While-Teil sofort ausgeführt wird

Mist, Klammern vergessen :)
Die CPU-Last in der Schleife wäre natürlich nicht null, ist halt busy waiting. Wenn File.copy() tatsächlich nicht blockiert, dann müsste man wohl tatsächlich mit synchronisierten Threads arbeiten. Oder du schreibst deine eigene copy()-Funktion, so in der Art

		public void copyFile(String source, String target)
		{
			StreamReader sr = new StreamReader(File.Open(source, FileMode.Open));
			StreamWriter srw = new StreamWriter(File.Open(target, FileMode.CreateNew));
			srw.Write(sr.ReadToEnd());
		}

Wenn die nicht blockt wird's seltsam.... :(
0

#9 Mitglied ist offline   DonElTomato 

  • Gruppe: aktive Mitglieder
  • Beiträge: 311
  • Beigetreten: 04. Oktober 05
  • Reputation: 0

geschrieben 28. April 2006 - 11:37

Oh. mhh ich hab den Fehler gefunden. Das File.Copy fungiert ganz normal, ich hab da was im Service falsch gemacht. Trotzdem danke für die Mühen!!!
0

#10 Mitglied ist offline   Lofote 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.526
  • Beigetreten: 24. August 04
  • Reputation: 1

geschrieben 28. April 2006 - 12:36

Hm, das interessiert mich jetzt schon genauer. Was ist denn da passiert?
0

#11 Mitglied ist offline   DonElTomato 

  • Gruppe: aktive Mitglieder
  • Beiträge: 311
  • Beigetreten: 04. Oktober 05
  • Reputation: 0

geschrieben 28. April 2006 - 12:58

AAAALLLLSOOO:

Ich habe ein Programm und einen Dienst. Diese beiden Kommunizieren quasi über eine im FileSystem abgelegte xml-Datei.

Wenn der dienst durch das Programm gesartet wird kopiert er diverse Dateien. dabei schreibt er seinen Momentanen Status in die XML File. Quasi welche Datei er grade kpoert etc.
Sobald er fertig ist schreibt auch dies in die XML Datei.

Das Programm ließt die XML-Datei alle 100ms aus und gibt die Informationen auf dem Fenster aus. Sobald es mitbekommt das in der XMl-Datei die Information über den beendeten Vorgang vorliegt zeigt es eine entsprechende MessageBox an.

Soweit so gut, aber das Programm hat sofort die MessageBox angezeigt obwohl die Dateien noch nicht kopiert waren.

Was der Fehler war: Es wird zwar geschriben das das Backup fertig ist aber danach nicht das es noch NICHT fertig ist. Das bedeutet das er bei jedem neustart die Informationen vom vorherigen durchlauf einließt und entsprechend die MessageBox anzeigt.

Problemlösung: Vor dem Start des Dienstes durch das Programm die Einstellungen entsprechend anpassen...
0

#12 Mitglied ist offline   Rika 

  • Gruppe: aktive Mitglieder
  • Beiträge: 11.533
  • Beigetreten: 11. Juni 03
  • Reputation: 2
  • Geschlecht:Männlich

geschrieben 28. April 2006 - 13:06

Das funktioniert trotzdem noch nicht synchron, weil sowohl der FileStream als auch das Dateisystem mit Puffern arbeiten.

Um das, was du willst, zu bewerkstelligen, musst du
1. den FileStream am Ende des Kopierens flush()en
2. die Datei für NON_CACHED_IO öffnen.

Das einfachste wäre jedoch, einfach die ganze Geschichte zu ignorieren.
Konnichiwa. Manga wo shitte masu ka? Iie? Gomenne, sonoyouna koto ga tabitabi arimasu. Mangaka ojousan nihongo doujinshi desu wa 'Clamp X', 'Ayashi no Ceres', 'Card Captor Sakura', 'Tsubasa', 'Chobits', 'Sakura Taisen', 'Inuyasha' wo 'Ah! Megamisama'. Hai, mangaka gozaimashita desu ni yuujin yori.
Eingefügtes Bild
Ja, mata ne!

(For sending email please use OpenPGP encryption and signing. KeyID: 0xA0E28D18)
0

#13 Mitglied ist offline   Lofote 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.526
  • Beigetreten: 24. August 04
  • Reputation: 1

geschrieben 28. April 2006 - 13:10

Ich glaube mit dem Cache kann er leben, es ging ihm nur darum dass die Programmzeile danach erst abgearbeitet wird, wenn die File.Copy ihren Teil so getan hat, dass es für alle anderen Programmen als vollständige (und nicht mehr gesperrte) Datei greifbar ist.
0

#14 Mitglied ist offline   DonElTomato 

  • Gruppe: aktive Mitglieder
  • Beiträge: 311
  • Beigetreten: 04. Oktober 05
  • Reputation: 0

geschrieben 28. April 2006 - 13:10

Wie mach ich denn das? Und macht das denn nicht die File.Copy()-methode?
0

#15 Mitglied ist offline   Lofote 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.526
  • Beigetreten: 24. August 04
  • Reputation: 1

geschrieben 28. April 2006 - 13:32

Nein, denn das Caching wird von Windows gemacht. Auch NTFS cacht mittels Transaktionsinformationen nochmals (was dann aber vernachlässigbar ist, weil unvollständige Transaktionen dann auch beim nächsten Reboot im Falle eines plötzlichen Stromausfalls gemacht werden kann) - in allen Fällen aus Performance-Gründen. Das passiert aber alles transparent für den User/die Anwendung, daher musst du dich im Regelfall nicht drum kümmern. Es sei denn du musst 100% sicherstellen, die Datei ist auch im Falle eines plötzliches Stromausfalles o.ä. am Ziel angekommen. Dann musst du Flushing-Methoden verwenden, ich weiss allerdings nicht, ob das auch tut, wenn das Ziel auf nem Netzwerklaufwerk liegt.
0

Thema verteilen:


  • 2 Seiten +
  • 1
  • 2

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0