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
块中的任何内容都将在 之后执行 try
和 catch
中的所有内容。因此finally
.. 它发生在最后。
我同意@ThePerplexedOne - 只要您不序列化 asyncron,数据就会写入您的文件。但是你是什么意思:“文件被破坏”?数据错误?文件被删除?有些不同?我的意思是如果我是对的,FileMode.Create 将创建或覆盖您的文件,...如果这是一种日志文件,我想这不是您想要做的...如果您想追加使用 FileMode.Append
或FileMode.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() 之前完成?的主要内容,如果未能解决你的问题,请参考以下文章