Wird eine using-Klausel diesen Stream schließen?
Habe ich anscheinend arbeitete mich in eine schlechte Codierung Gewohnheit. Hier ist ein Beispiel für den code, ich habe geschrieben:
using(StreamReader sr = new StreamReader(File.Open("somefile.txt", FileMode.Open)))
{
//read file
}
File.Move("somefile.txt", "somefile.bak"); //can't move, get exception that I the file is open
Dachte ich, dass da die using
- Klausel explizit genannt Close()
und Dispose()
auf die StreamReader
dass die FileStream
wäre Sie geschlossen.
Nur so konnte ich das problem beheben, die ich hatte wurde durch die änderung der oben block:
using(FileStream fs = File.Open("somefile.txt", FileMode.Open))
{
using(StreamReader sr = new StreamReader(fs))
{
//read file
}
}
File.Move("somefile.txt", "somefile.bak"); //can move file with no errors
Sollte die Schließung der StreamReader
durch die Entsorgung in den ersten block auch in der Nähe der zugrunde liegenden FileStream
? Oder, war ich Irre?
Bearbeiten
Entschied ich mich zum posten der eigentlichen problematischen code-block, um zu sehen, ob wir bekommen können Sie unten auf dieser. Ich bin einfach nur neugierig jetzt.
Dachte ich, ich hätte ein problem in der using
- Klausel, also habe ich alles ausgebaut und es ist immer noch nicht kopieren können, zu jeder Zeit. Ich erstelle die Datei, in der diese Methode aufgerufen wird, so dass ich denke nichts anderes hat einen Griff öffnen auf die Datei. Ich habe auch überprüft, ob die Zeichenfolgen zurückgegeben, die von der Path.Combine
Anrufe korrekt sind.
private static void GenerateFiles(List<Credit> credits)
{
Account i;
string creditFile = Path.Combine(Settings.CreditLocalPath, DateTime.Now.ToString("MMddyy-hhmmss") + ".credits");
StreamWriter creditsFile = new StreamWriter(File.Open(creditFile, FileMode.Create));
creditsFile.WriteLine("code\inc");
foreach (Credit c in credits)
{
if (DataAccessLayer.AccountExists(i))
{
string tpsAuth = DataAccessLayer.GetAuthCode(i.Pin);
creditsFile.WriteLine(String.Format("{0}{1}\t{2:0.00}", i.AuthCode, i.Pin, c.CreditAmount));
}
else
{
c.Error = true;
c.ErrorMessage = "NO ACCOUNT";
}
DataAccessLayer.AddCredit(c);
}
creditsFile.Close();
creditsFile.Dispose();
string dest = Path.Combine(Settings.CreditArchivePath, Path.GetFileName(creditFile));
File.Move(creditFile,dest);
//File.Delete(errorFile);
}
DateTime.Nun.ToString("Mmttjj-hhmmss")
, Wie viele Dateien Sie erstellen pro Sekunde? InformationsquelleAutor der Frage scottm | 2009-04-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja,
StreamReader.Dispose
schließt der zugrunde liegende stream (für alle öffentliche Wege anlegen). Allerdings gibt es eine schönere alternative:Dies hat den Vorteil, dass es öffnet sich das zugrunde liegende stream mit einem Hinweis auf Windows, werden Sie den Zugriff auf hintereinander.
Hier ist eine test-app, die zeigt die erste version für mich arbeiten. Ich versuche nicht zu sagen, das ist der Beweis für etwas bestimmtes, aber ich würde gerne wissen, wie gut es für Sie arbeitet.
Wenn das funktioniert, deutet darauf hin, dass es etwas mit dem zu tun, was Sie tun, während Sie Lesen...
Und nun, hier ist eine verkürzte version von Ihr bearbeiteten Frage-code - was wiederum funktioniert gut für mich, auch auf einem Netzwerk-share. Beachten Sie, dass ich mich geändert habe
FileMode.Create
zuFileMode.CreateNew
- sonst kann es zu könnte noch eine app mit einem Griff auf die alte Datei möglicherweise. Macht diese Arbeit für Sie?InformationsquelleAutor der Antwort Jon Skeet
Hinweis - die Verwendung von Blöcken müssen nicht verschachtelt werden in eigenen blocks - Sie können fortlaufend sein, wie in:
Die Reihenfolge der Entsorgung in diesem Fall ist noch die selbe, wie die verschachtelten Blöcke (dh, der StreamReader immer noch entsorgen, bevor die FileStream in diesem Fall).
InformationsquelleAutor der Antwort Not Sure
Ich würde versuchen, Sie zu nutzen
FileInfo.Open()
undFileInfo.MoveTo()
stattFile.Open()
undFile.Move(
). Sie könnten auch versuchen, zu verwendenFileInfo.OpenText()
. Dies sind aber nur Vorschläge.InformationsquelleAutor der Antwort MartinStettner
Gibt es irgendeine Möglichkeit, dass etwas anderes hat, eine Sperre zu somefile.txt?
Einen einfachen check von einem lokalen (auf die Datei) cmd line
kann auch geben Ihnen einige Hinweise, wenn irgendetwas anderes hat eine Sperre.
Alternativ können Sie auch so etwas wie FileMon noch mehr details, und überprüfen Sie, dass Ihre app ist die Freigabe richtig.
InformationsquelleAutor der Antwort Zhaph - Ben Duguid
Da dieses nicht zu sein scheinen ein coding Problem, ich werde meine syadmin Hut auf und ein paar Anregungen bieten.
Edit: Wenn du es fangen kannst, die im Gesetz vom server-Rechner, dann Sysinternal ' s Griff wird Ihnen sagen, was hat es zu öffnen.
InformationsquelleAutor der Antwort Mark Brackett