BinaryFormatter.Serialize() 是不是在 FileStream.Flush() 和 FileStream.Close() 之前完成?

Posted

技术标签:

【中文标题】BinaryFormatter.Serialize() 是不是在 FileStream.Flush() 和 FileStream.Close() 之前完成?【英文标题】:Does the BinaryFormatter.Serialize() finish before FileStream.Flush() and FileStream.Close()?BinaryFormatter.Serialize() 是否在 FileStream.Flush() 和 FileStream.Close() 之前完成? 【发布时间】:2017-04-22 07:13:53 【问题描述】:

我将我的班级列表保存到二进制文件中并使用 FileStream 和 BinaryFormatter。

private void SaveCustomers()

  FileStream fs = null;

  try
  
    fs = new FileStream( Application.StartupPath + dataPath + @"\" + customersFilename, FileMode.Create, FileAccess.Write );
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(fs, customers);

  
  catch (Exception ex)
  
    MessageBox.Show( ex.Message, "Fehler beim speichern der Besucherdaten", MessageBoxButtons.OK, MessageBoxIcon.Error );
  
  finally
  
    if (fs != null)
    
      fs.Flush();
      fs.Close();
    
  

在我的程序中的某个时刻,文件被“破坏”了。由于这是唯一有权写入文件的方法,我认为这种方法是问题所在。

我的假设是当 Filestream 被刷新和关闭时 BinaryFormatter 没有完成。

这只是最近才发生的,因为文件一开始大约 8 MB,它运行得完美无缺。

我的假设是否正确?还是完全不同。

private void LoadCustomers()

  FileStream fs = null;

  try
  
    fs = new FileStream( Application.StartupPath + dataPath + @"\" + customersFilename, FileMode.OpenOrCreate, FileAccess.Read );
    BinaryFormatter bf = new BinaryFormatter();
    customers = (List<Customer>)bf.Deserialize( fs );

    if (customers == null) customers = new List<Customer>();
  
  catch (Exception ex)
  
    MessageBox.Show( ex.Message, "Fehler beim laden der Besucherdaten", MessageBoxButtons.OK, MessageBoxIcon.Error );
  
  finally
  
    if (fs != null)
    
      fs.Flush();
      fs.Close();
    
  

最后一个代码是我的阅读器。

【问题讨论】:

finally 块中的任何内容都将在 之后执行 trycatch 中的所有内容。因此finally.. 它发生在最后 我同意@ThePerplexedOne - 只要您不序列化 asyncron,数据就会写入您的文件。但是你是什么意思:“文件被破坏”?数据错误?文件被删除?有些不同?我的意思是如果我是对的,FileMode.Create 将创建或覆盖您的文件,...如果这是一种日志文件,我想这不是您想要做的...如果您想追加使用 FileMode.AppendFileMode.OpenOrCreate 在写入之前尝试删除文件。我遇到了一个问题,我用FileMode.Create 写入了一个文件,并且在导致文件保存无效数据之前它没有正确截断。在写入之前删除修复它。 在写入之前它接近 8 MB 大,而在仅 7KB 之后我没有更改数据。之后我无法读取文件 这样的 API 将无法使用。不像那样。该错误在其他地方,而不是在 AFAICT 发布的代码中。 【参考方案1】:

您使用FileMode.Create,这会导致您的程序在您的文件已经存在时覆盖它。 (我想这就是您所说的“文件被破坏”的意思。

如果你想添加新行,你应该使用FileMode.OpenOrCreate,比如在日志文件中......

参见:MSDN 创建:

指定操作系统应该创建一个新文件。如果文件已经存在,它将被覆盖。这需要 FileIOPermissionAccess.Write 权限。 FileMode.Create相当于请求如果文件不存在就使用CreateNew;否则,使用截断。如果文件已经存在但为隐藏文件,则抛出 UnauthorizedAccessException 异常。

【讨论】:

我在一个列表中拥有我需要的所有信息,并且在一个文件中需要所有信息。如果我使用 openorcreate 它会检查发生了什么变化吗? 如果您使用OpenOrCreate,它会将数据附加到您的 FileStream 相关文件中。你想覆盖你的旧信息吗?如果是这样,Create 是对的,就像您使用的那样。因此,正如您在文件变得大于 8MB 时所写的那样,您的文件是否像 8Kb 一样写入?发生这种情况时,您的消息框中是否显示错误? 如果我稍后尝试加载文件,则会发生错误。当我试图保护它时,没有异常抛出。读取时的错误类似于:加载数据时的流溢出(免费翻译) 嗯,据我了解,您的代码很好 - 读取文件时没有更详细的错误,或者可能是我们无法进一步帮助您的异常。也许您的客户列表有问题? 现在读取时的确切错误是:在处理完成之前到达了流端。

以上是关于BinaryFormatter.Serialize() 是不是在 FileStream.Flush() 和 FileStream.Close() 之前完成?的主要内容,如果未能解决你的问题,请参考以下文章