问题描述
这是这个问题的后续问题:
Difference between file path and file stream?
我使用的 Microsoft.sqlServer.Dac.BacPackage
包含一个带有 2 个重载的 Load
方法 - 一个接收字符串路径,一个接收 Stream
。
这是 Load 方法的文档:
这两者到底有什么区别?我假设字符串路径的重载首先将所有文件保存在内存中,而流不是吗?还有其他区别吗?
解决方法
不,通常不会一次完全加载文件。
string path
参数通常意味着它只会将文件作为 FileStream
打开并将其传递给函数的其他版本。除非请求,否则流没有理由将文件完全加载到内存中。
Stream
参数意味着 您 打开文件并传递结果 Stream
。您还可以传递任何其他类型的 Stream
,例如网络流、zip 或解密流、内存支持的流,等等。
简答:
事实上你有两种方法,一种接受文件名,一种接受流,只是为了方便。在内部,具有文件名的将打开文件作为流并调用另一个方法。
更长的答案
您可以将流视为字节序列。使用流而不是 byte[]
或 List<byte>
的原因是,如果序列真的非常大,并且您不需要一次访问所有字节,它会在处理之前将所有字节放入内存是一种浪费。
例如,如果您想计算文件中所有字节的校验和:在开始计算总和之前,您不需要将所有数据都放入内存中。事实上,任何可以有效地将字节一个一个地交付给您的东西就足够了。
这就是人们希望以流的形式读取文件的原因。
人们想要一个流作为他们数据输入的原因是他们想让调用者有机会指定他们的数据来源:调用者可以提供一个从文件中读取的流,也可以提供一个流来自互联网、数据库或文本框的数据,该过程并不关心,只要它可以一个一个或有时每个字节块读取字节:
using (Stream fileStream = File.Open(fileName)
{
ProcessInputData(fileStream);
}
或者:
byte[] bytesToProcess = ...
using (Stream memoryStream = new MemoryStream(bytesToProcess))
{
ProcessInputData(memoryStream);
}
或者:
string operatorInput = this.textBox1.Text;
using (Stream memoryStream = new MemoryStream(operatorInput))
{
ProcessInputData(memoryStream);
}
结论
方法在它们的接口中使用流来表明它们不需要一次在内存中的所有数据。一个接一个或每个块就足够了。调用者可以自由决定数据的来源。