答案 0 :(得分:15)
MSDN并非100%明确,但Jon Skeet正在说“Flush”,所以在关闭/处置之前这样做。它不会受伤,对吧?
之前写入缓冲区的任何数据都会被复制到该文件中 文件流已关闭,因此无需先调用Flush 调用Close。调用Close后,对文件执行任何操作 流可能引发异常。关闭一次后,它就被调用了 如果再次打电话,什么都不做。
处理不是那么清楚:
此方法通过将任何更改写入后备来处理流 存储和关闭流以释放资源。
备注:评论员可能是正确的,并非从Flush中100%清楚:
覆盖实现缓冲区的流上的Flush。使用此方法 将任何信息从底层缓冲区移动到其目标, 清除缓冲区,或两者兼而有之。根据对象的状态,你 可能必须修改流中的当前位置(for 例如,如果底层流支持搜索)。另外 信息见CanSeek。
使用StreamWriter或BinaryWriter类时,请不要刷新 基本流对象。相反,使用类的Flush或Close方法, 这可以确保将数据刷新到基础流 首先然后写入文件。
var textBytes = Encoding.ASCII.GetBytes("Test123");
using (var fileTest = System.IO.File.Open(@"c:\temp\fileNoCloseNoFlush.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes,0,textBytes.Length);
}
using (var fileTest = System.IO.File.Open(@"c:\temp\fileCloseNoFlush.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes, 0, textBytes.Length);
fileTest.Close();
}
using (var fileTest = System.IO.File.Open(@"c:\temp\fileFlushNoClose.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes, 0, textBytes.Length);
fileTest.Flush();
}
using (var fileTest = System.IO.File.Open(@"c:\temp\fileCloseAndFlush.txt", FileMode.CreateNew))
{
fileTest.Write(textBytes, 0, textBytes.Length);
fileTest.Flush();
fileTest.Close();
}
我能说什么...所有文件都有文字 - 也许这只是太少的数据?
var rnd = new Random();
var size = 1024*1024*10;
var randomBytes = new byte[size];
rnd.NextBytes(randomBytes);
using (var fileTest = System.IO.File.Open(@"c:\temp\fileNoCloseNoFlush.bin", FileMode.CreateNew))
{
fileTest.Write(randomBytes, 0, randomBytes.Length);
}
using (var fileTest = System.IO.File.Open(@"c:\temp\fileCloseNoFlush.bin", FileMode.CreateNew))
{
fileTest.Write(randomBytes, 0, randomBytes.Length);
fileTest.Close();
}
using (var fileTest = System.IO.File.Open(@"c:\temp\fileFlushNoClose.bin", FileMode.CreateNew))
{
fileTest.Write(randomBytes, 0, randomBytes.Length);
fileTest.Flush();
}
using (var fileTest = System.IO.File.Open(@"c:\temp\fileCloseAndFlush.bin", FileMode.CreateNew))
{
fileTest.Write(randomBytes, 0, randomBytes.Length);
fileTest.Flush();
fileTest.Close();
}
再一次 - 每个文件都得到了它的字节......对我来说,看起来它正在做我从MSDN上读到的内容:如果你在处理之前调用Flush或Close并不重要......对此有任何想法吗?
答案 1 :(得分:12)
你没有在Flush()
上致电Close()/Dispose()
,FileStream
会为你做,正如你从中看到的那样源代码:
http://referencesource.microsoft.com/#mscorlib/system/io/filestream.cs,e23a38af5d11ddd3
[System.Security.SecuritySafeCritical] // auto-generated
protected override void Dispose(bool disposing)
{
// Nothing will be done differently based on whether we are
// disposing vs. finalizing. This is taking advantage of the
// weak ordering between normal finalizable objects & critical
// finalizable objects, which I included in the SafeHandle
// design for FileStream, which would often "just work" when
// finalized.
try {
if (_handle != null && !_handle.IsClosed) {
// Flush data to disk iff we were writing. After
// thinking about this, we also don't need to flush
// our read position, regardless of whether the handle
// was exposed to the user. They probably would NOT
// want us to do this.
if (_writePos > 0) {
FlushWrite(!disposing); // <- Note this
}
}
}
finally {
if (_handle != null && !_handle.IsClosed)
_handle.Dispose();
_canRead = false;
_canWrite = false;
_canSeek = false;
// Don't set the buffer to null, to avoid a NullReferenceException
// when users have a race condition in their code (ie, they call
// Close when calling another method on Stream like Read).
//_buffer = null;
base.Dispose(disposing);
}
}
答案 2 :(得分:4)
我一直在跟踪一个新引入的错误,似乎表明.NET 4在流处理时不能可靠地刷新磁盘更改(与.NET 2.0和3.5不同,它总是可靠地执行)。
.NET 4 FileStream类已经在.NET 4中进行了重大修改,虽然Flush *()方法已被重写,但似乎已经忘记了.Dispose()。
这导致文件不完整。
答案 3 :(得分:3)
既然你已经声明你理解那个关闭&amp; dispose称为flush方法如果没有被用户代码明确调用,我相信(通过close而不刷新)你实际上希望有可能丢弃对{{ 1}},如有必要。
如果这是正确的,单独使用FileStream
将无济于事。您需要将此文件加载到FileStream
(或数组中,具体取决于您修改其内容的方式),然后在完成后决定是否要保存更改。
显然,问题在于文件大小。 MemoryStream
使用有限大小的写缓冲区来加速操作,但一旦耗尽,就需要刷新更改。由于.NET内存限制,您只能在内存中加载较小的文件,如果您需要完全保存它们。
更简单的替代方法是制作文件的磁盘副本,并使用普通FileStream
进行处理。完成后,如果您需要放弃更改,只需删除临时文件,否则用修改后的副本替换原始文件。
答案 4 :(得分:-1)
将FileStream
换行BufferedStream
并在缓冲流之前关闭文件流。
var fs = new FileStream(...);
var bs = new BufferedStream(fs, buffersize);
bs.Write(datatosend, 0, length);
fs.Close();
try {
bs.Close();
}
catch (IOException) {
}
答案 5 :(得分:-1)
在大循环中使用Flush()是值得的。 当你必须在一个循环中读取和写入一个大文件时。在其他情况下,缓冲区或计算机足够大,并且在没有制作一个Flush()之前关闭()并不重要。
示例:您必须阅读大文件(以一种格式)并将其写入.txt
StreamWriter sw = .... // using StreamWriter
// you read the File ...
// and now you want to write each line for this big File using WriteLine ();
for ( .....) // this is a big Loop because the File is big and has many Lines
{
sw.WriteLine ( *whatever i read* ); //we write here somrewhere ex. one .txt anywhere
sw.Flush(); // each time the sw.flush() is called, the sw.WriteLine is executed
}
sw.Close();
这里使用Flush()非常重要;因为否则每个writeLine都保存在缓冲区中,直到缓冲区为frull或程序到达sw.close()之后才会写入;
我希望这有助于理解Flush的功能
答案 6 :(得分:-2)
我认为使用简单的使用语句是安全的,该语句在调用 GetBytes()后关闭流;
public static byte[] GetBytes(string fileName)
{
byte[] buffer = new byte[4096];
using (FileStream fs = new FileStream(fileName))
using (MemoryStream ms = new MemoryStream())
{
fs.BlockCopy(ms, buffer, 4096); // extension method for the Stream class
fs.Close();
return ms.ToByteArray();
}
}