2017-06-08 67 views
2

我正在寫一個控制檯程序。我得到的代碼工作,但我想把它變成一個通用的功能,使使用不同Stream源(如MemoryStream)。爲什麼FileStream不可寫?

這是我的計劃:

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); 
       } 
      } 
     } 
    } 
} 

好,做工精細。現在,讓我們把它更通用:

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); 
      } 
     } 
    } 
} 

,但我得到就行了異常:using (var writer = new MarcStreamWriter(fs2, "UTF-8"))

類型「System.ArgumentException」未處理的異常出現在mscorlib.dll
更多信息:流不可寫。

堆棧跟蹤

在System.IO.BinaryWriter..ctor(流輸出,編碼方式進行編碼,布爾leaveOpen)
在MARC4J.Net.MarcStreamWriter..ctor(流輸出,字符串編碼,布爾allowOversizeRecord)
在MARC4J.Net.MarcStreamWriter..ctor(流輸出,串編碼)
在SummonImport.Program.ConvertXmlMarcToMarc(流鰭,流FOUT)在F:!! LocalRepository \ Libraries_Apps \ SummonImport \行李箱\ relea本身\ SummonImport \ SummonImport \ Program.cs的:線35 F中
在SummonImport.Program.Main(字串[] args):!! LocalRepository \ Libraries_Apps \ SummonImport \樹幹\釋放\ SummonImport \ SummonImport \ Program.cs中:線20
在System.AppDomain._nExecuteAssembly(RuntimeAssembly組件,字串[] args)
在System.AppDomain.ExecuteAssembly(字符串assemblyFile,證據assemblySecurity,字串[] args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object s泰特,布爾preserveSyncCtx)
在System.Threading.ExecutionContext.Run(的ExecutionContext的ExecutionContext,ContextCallback回調,對象的狀態,布爾preserveSyncCtx)
在System.Threading.ExecutionContext.Run(的ExecutionContext的ExecutionContext,ContextCallback回調,對象狀態)
在System.Threading.ThreadHelper.ThreadStart()

+0

什麼是堆棧跟蹤? – SLaks

+0

添加堆棧跟蹤 – solidau

+0

文件被標記爲只讀或您正在運行的用戶沒有權限寫入文件? –

回答

2

在第一個示例中,您打開並關閉每個循環上的文件。

在你的第二個例子中,你沒有重新打開該文件,可能是當編輯器被處置時它正在關閉基礎流。該異常將在循環中第二次發生。

嘗試移動using語句來包裝的循環,它應該工作

+0

好吧,我移動了'MarcStreamWriter'使用語句包裝整個功能,現在它可以工作。我明白你在每個循環中關閉/重新打開它的意思 - 謝謝! – solidau

1

你需要接受一個FileAccess參數FileStream constructor

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

FileMode.OpenOrCreate自身是不夠的,使其可寫:

指定操作系統應打開一個文件,如果存在的話;否則,應該創建一個新文件。如果文件被打開與FileAccess.Read,需要FileIOPermissionAccess.Read許可。如果文件訪問是FileAccess.Write,需要FileIOPermissionAccess.Write許可。如果文件使用FileAccess打開。ReadWrite,都需要FileIOPermissionAccess.Read和FileIOPermissionAccess.Write權限。

+0

我試圖添加,仍然得到異常。 – solidau

+0

@solidau我無法複製錯誤。在調用函數之前,使用調試器檢查'fs2.CanWrite'。它爲我顯示「真實」。無論你的'MarcStreamWriter'構造函數在做什麼,這可能是個問題? – itsme86

+0

CanWrite = true hmmmmmmmm ...構造函數工作正常,如果我把'使用'之前 – solidau