c# - 我需要手动刷新 StreamWriter 吗?
问题描述
我有以下情况。
我通过逐行读取巨大的 csv 文件来执行拆分功能。每行都有categoryId
. 基于该 ID,我需要将此行写入单独的文件。
为此,我正在执行以下操作:
- 逐行读取巨大的文件。
- 阅读每一行后,我打开一个基于 categoryId 的新流(仅当流尚未打开时)。将行写入流,然后保持流打开,因为大文件中可能有更多行。
- 最后,处理完大文件中的所有行后,我将关闭所有打开的流。这会强制刷新并关闭连接。
我的问题是。我是否需要手动调用 Flush() 让我们说 -> 每记录 100 行,或者这是由 StreamWriter 本身处理的东西。我在网上读到有一个缓冲区满时会自动刷新,但我不确定这是否属实。我担心的是,如果它不刷新并等待大文件结束,我可能最终会将整个文件加载到内存中。
这是代码的一部分,看看在说什么:
try
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
var locationId = line.Split(',')[0];
var gdProjectId = GetGDProjectId(locationId);
var blobName = $"{gdProjectId}/{DateTime.UtcNow.ToString("dd-MM-yyyy")}/{DateTime.UtcNow.ToString("HH-mm-ss")}-{Guid.NewGuid()}.csv";
if (!openWriters.ContainsKey(gdProjectId))
{
var blockBlobClient = containerClient.GetBlockBlobClient(blobName);
var newWriteStream = await blockBlobClient.OpenWriteAsync(true);
openWriters.Add(gdProjectId, new StreamWriter(newWriteStream, Encoding.UTF8));
}
var writer = openWriters[gdProjectId];
await writer.WriteLineAsync(line);
// SHOULD I MANUALLY INVOKE FLUSH ON EVERY {X} lines processed ?
// TODO: Check if we need to manually flush or the streamwriter does it for us when the buffer is full.
// await writer.FlushAsync();
}
}
catch (Exception ex)
{
throw;
}
finally
{
// we are always closing the writers no matter if the operation is successful or not.
foreach (var oStream in openWriters)
{
oStream.Value.Close();
}
}
解决方案
Flush
(在StreamWriter
实现中)只是将数据从缓冲区发送到底层流,然后调用Flush
底层流,即(伪代码):
underlyingStream.Write(GetDataFromBuffer());
bufferPosition = 0; // "clears" buffer
underlyingStream.Flush();
缓冲区大小是恒定的。默认情况下,它大约是 2-4KiB。但可以在构造函数中手动设置更大的值。Flush
不改变缓冲区大小。Flush
因此,每 100 行调用一次不会给您任何帮助。
问:“我是否需要手动调用 Flush() 让我们说 -> 每 100 行...”
不,它不会为您节省任何记忆。它只会更早地将数据写入底层流 - 即它不会等待缓冲区已满。
提示:如果属性AutoFlush
设置为 true,Flush
将在每次 WriteXYZ 方法调用后自动调用。
问:“我担心的是,如果它不刷新并等待大文件结束,我可能最终会将整个文件加载到内存中。”
缓冲区大小是恒定的。打电话Flush
也无济于事。
但...
仅从角度来看,一切都是真实的StreamWriter
。
因为StreamWriter
只持有对某个Stream
实例的引用,所以如果不知道该Stream
实例的具体实现(Stream
is abstract
),您就无法预测内存使用情况。
您应该创建新问题,例如:“我需要手动刷新 XyzStream”吗?(如果没有已经发布的问题)。
推荐阅读
- julia - 如何在 Julia 中硬编码结构变量?
- python - python过滤行匹配keyworks
- python - 如何像普通用户一样自动连接到 Twitch 流
- python - 如何从其他两个 csv 文件创建新文件?
- r - 尝试使用 R 中的多个 if else 语句创建新列
- ios - iOS Objective-c 同步
- python - 正确地将 NumPy 数组转换为在 gpu 上运行的 PyTorch 张量
- algorithm - 有约束的资源分配算法
- python - 表单函数始终作为有效传递
- powershell - Powershell:如何找出哪些正在运行的服务不属于操作系统和非 MS