2017-06-08 3 views
2

Ich schreibe ein Konsolenprogramm. Ich habe den Code zu arbeiten, aber ich möchte es in eine generische Funktion ändern, um die Verwendung von verschiedenen Stream Quellen (wie MemoryStream) zu ermöglichen.Warum ist FileStream nicht beschreibbar?

Hier ist mein Programm:

private static void Main(string[] args) 
{ 
    using (var fs = new FileStream("f:\\!temp\\marcXmlRecords.mxml", FileMode.Open)) 
    { 
     var reader = new MarcXmlReader().Read(fs); 

     foreach (var record in reader) 
     { 
      var leader = record.Leader; 
      var controlFields = record.GetControlFields(); 
      var dataFields = record.GetDataFields(); 
      var allFields = record.GetVariableFields(); 

      using (var fs2 = new FileStream("f:\\!temp\\marcRecords.mrc", 
       FileMode.OpenOrCreate)) 
      { 
       using (var writer = new MarcStreamWriter(fs2, "UTF-8")) 
       { 
        var wrecord = MarcFactory.Instance.NewRecord(); 
        wrecord.Leader = record.Leader; 

        foreach (var cfield in controlFields) 
        { 
         wrecord.AddVariableField(cfield); 
        } 

        foreach (var dfield in dataFields) 
        { 
         wrecord.AddVariableField(dfield); 
        } 

        foreach (var afield in allFields) 
        { 
         wrecord.AddVariableField(afield); 
        } 

        writer.Write(wrecord); 
       } 
      } 
     } 
    } 
} 

Ok, funktioniert gut. Nun wollen wir machen es generic:

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     using (var fs = new FileStream("f:\\!temp\\marcXmlRecords.mxml", FileMode.Open)) 
     { 
      using (var fs2 = new FileStream("f:\\!temp\\marcRecords.mrc", 
       FileMode.OpenOrCreate)) 
      { 
       ConvertXmlMarcToMarc(fs, fs2); 
      } 
     } 
    } 

    private static void ConvertXmlMarcToMarc(Stream fin, Stream fout) 
    { 
     var reader = new MarcXmlReader().Read(fin); 

     foreach (var record in reader) 
     { 
      var leader = record.Leader; 
      var controlFields = record.GetControlFields(); 
      var dataFields = record.GetDataFields(); 
      var allFields = record.GetVariableFields(); 

      using (var writer = new MarcStreamWriter(fout, "UTF-8")) 
      { 
       var wrecord = MarcFactory.Instance.NewRecord(); 
       wrecord.Leader = record.Leader; 

       foreach (var cfield in controlFields) 
       { 
        wrecord.AddVariableField(cfield); 
       } 

       foreach (var dfield in dataFields) 
       { 
        wrecord.AddVariableField(dfield); 
       } 

       foreach (var afield in allFields) 
       { 
        wrecord.AddVariableField(afield); 
       } 

       writer.Write(wrecord); 
      } 
     } 
    } 
} 

Aber ich erhalte eine Ausnahme auf der Linie: using (var writer = new MarcStreamWriter(fs2, "UTF-8")):

Eine nicht behandelte Ausnahme des Typs 'System.ArgumentException' ist in mscorlib.dll aufgetreten
Weitere Informationen : Stream war nicht beschreibbar.

Stack Trace

bei System.IO.BinaryWriter..ctor (Stream-Ausgang, Encoding Codierung, Boolean Leaveopen)
bei MARC4J.Net.MarcStreamWriter..ctor (Stream-Ausgang, String-Codierung, Boolean allowOversizeRecord)
bei MARC4J.Net.MarcStreamWriter..ctor (Stream-Ausgabe, String-Codierung)
bei SummonImport.Program.ConvertXmlMarcToMarc (Stream fin, Stream fout) in F: !! LocalRepository \ Libraries_Apps \ SummonImport \ Stamm/relea se \ SummonImport \ SummonImport \ Program.cs: Zeile 35
bei SummonImport.Program.Main (String [] args) in F: !! LocalRepository \ Libraries_Apps \ SummonImport \ Stamm \ Release \ SummonImport \ SummonImport \ Program.cs: Zeile 20
bei System.AppDomain._nExecuteAssembly (RuntimeAssembly Montage, String [] args)
bei System.AppDomain.ExecuteAssembly (String assembly, Evidence assemblySecurity, String [] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ThreadHelper.ThreadStart_Context (Objektzustand)
bei System.Threading.ExecutionContext.RunInternal (ExecutionContext executionContext, ContextCallback Callback, Objekt s tate, Boolesche preserveSyncCtx)
bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, Contextcallback, Objektzustand, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, Context Rückruf, Objektzustand)
bei System.Threading.ThreadHelper.ThreadStart()

+0

Was ist die Stack-Ablaufverfolgung? – SLaks

+0

hinzugefügt Stack-Trace – solidau

+0

eine Chance, die Datei als schreibgeschützt markiert ist oder der Benutzer, den Sie ausführen, hat keine Rechte zum Schreiben in die Datei? –

Antwort

2

Im ersten Beispiel öffnen und schließen Sie die Datei in jeder Schleife.

In Ihrem zweiten Beispiel öffnen Sie die Datei nicht erneut. Die Wahrscheinlichkeit ist, dass der Writer beim Schließen des Writers den zugrunde liegenden Stream schließt. Die Ausnahme tritt beim zweiten Durchlauf der Schleife auf.

Versuchen Sie die using-Anweisung zu verschieben, um die for-Schleife zu wickeln, und es sollte funktionieren

+0

OK, ich habe den' MarcStreamWriter' mit Anweisung verschoben um die gesamte Funktion zu umhüllen und es funktioniert jetzt. Ich verstehe, was du damit meinst, es auf jeder Schleife zu schließen/wieder zu öffnen - danke! – solidau

1

Sie benötigen die FileStream constructor, die einen FileAccess Parameter nimmt:

using (var fs2 = new FileStream("f:\\!temp\\marcRecords.mrc", FileMode.OpenOrCreate, FileAccess.Write)) 

FileMode.OpenOrCreate allein ist nicht genug, um es beschreibbar zu machen:

Gibt an, dass das Betriebssystem eine Datei öffnen soll, wenn sie existiert; Andernfalls sollte eine neue Datei erstellt werden. Wenn die Datei mit FileAccess.Read geöffnet wird, ist die FileIOPermissionAccess.Read-Berechtigung erforderlich. Wenn der Dateizugriff FileAccess.Write ist, ist die FileIOPermissionAccess.Write-Berechtigung erforderlich. Wenn die Datei mit FileAccess geöffnet wird.ReadWrite, beide FileIOPermissionAccess.Read und FileIOPermissionAccess.Write Berechtigungen sind erforderlich.

+0

ich versuchte, das hinzufügen, immer noch die Ausnahme. – solidau

+0

@solidau Ich kann den Fehler nicht duplizieren. Verwenden Sie den Debugger, um 'fs2.CanWrite' zu ​​prüfen, bevor Sie Ihre Funktion aufrufen. Es zeigt 'True' für mich. Vielleicht ist es ein Problem in was auch immer Ihr 'MarcStreamWriter' Konstruktor tut? – itsme86

+0

CanWrite = true hmmmmmmmm ... Konstruktor funktioniert gut, wenn ich 'using' kurz vor – solidau

Verwandte Themen