2017-06-08 58 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