0

This is a follow up question to this question:

Difference between file path and file stream?

I didn't fully understand everything answered in the linked question.

I am using the Microsoft.SqlServer.Dac.BacPackage which contains a Load method with 2 overloads - one that receives a string path and one that receives a Stream.

This is the documentation of the Load method:

https://learn.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.dac.bacpackage.load?view=sql-dacfx-150

What exactly is the difference between the two? Am I correct in assuming that the overloading of the string path saves all the file in the memory first, while the stream isn't? Are there other differences?

CodeMonkey
  • 11,196
  • 30
  • 112
  • 203
  • The string file path overload likely just opens a file stream and then passes that to the Stream overload. If you already have a FileStream or perhaps a MemoryStream containing the Dac you'd use the Stream overload but if all you had was the filename and didn't want to manage the FileStream yourself you'd use the string overload. Doubtful there's any difference other than that – pinkfloydx33 Feb 21 '21 at 10:23
  • 1
    I think you should read up on [what a stream is](https://stackoverflow.com/questions/5144794/what-does-stream-mean-what-are-its-characteristics). You are currently asking how the two different methods are implemented, which you need to look at the source code to understand. What exactly is your interest in this? – Xerillio Feb 21 '21 at 10:24
  • You can refer this https://social.msdn.microsoft.com/Forums/vstudio/en-US/924dfa2e-62c1-4c5c-b1ef-04b0d0a3550f/difference-between-file-and-stream?forum=netfxbcl – Vivek Nuna Feb 21 '21 at 10:32
  • @Xerillio That's about what I wrote about loading the bacpac. I can have some huge bacpacs I want to load and I don't want it to be loaded to the memory entirely, but that it would be loaded in a stream – CodeMonkey Feb 21 '21 at 11:58
  • 1
    @YonatanNir In that case, only the creators of *Microsoft.SqlServer.Dac* will be able to answer your question or if you can find the source code you can check there. Everyone else will only be able to give a qualified guess. For that reason I don't think this question belongs on SO. – Xerillio Feb 21 '21 at 12:20

2 Answers2

0

No, the file will not usually be fully loaded all at once.

A string path parameter normally means it will just open the file as a FileStream and pass it to the other version of the function. There is no reason why the stream should fully load the file into memory unless requested.

A Stream parameter means you open the file and pass the resulting Stream. You could also pass any other type of Stream, such as a network stream, a zip or decryption stream, a memory-backed stream, anything really.

Charlieface
  • 52,284
  • 6
  • 19
  • 43
  • How can I check if what you said about the string overload is indeed the case? – CodeMonkey Feb 21 '21 at 12:08
  • I see no reason to believe it would be any different than the probably hundred other such pairs of functions in .NET, it's a pretty standard. You would need to see the source code to be sure, I can't find it on Github, so try decompiling it yourself. – Charlieface Feb 21 '21 at 12:37
  • Lets say it is like that, does it mean that the bacpac file is NOT loaded fully to the memory? – CodeMonkey Feb 21 '21 at 12:45
  • Correct, it will be loaded bit by bit. It could be that when it's finished then whole thing is processed and loaded into objects (depending on what the function is actually supposed to do), but the actual file bytes as a whole blob are not present in memory all at once, so this definitely won't require memory twice the size of the file. – Charlieface Feb 21 '21 at 12:51
0

Short answer:

The fact that you have two methods, one that accepts a filename and one that accepts a stream is just for convenience. Internally, the one with the filename will open the file as a stream and call the other method.

Longer answer

You can consider a stream as a sequence of bytes. The reason to use a stream instead of a byte[] or List<byte>, is, that if the sequence is really, really large, and you don't need to have access to all bytes at once, it would be a waste to put all bytes in memory before processing them.

For instance, if you want to calculate the checksum for all bytes in a file: you don't need to put all data in memory before you can start calculating the sum. In fact, anything that efficiently can deliver you the bytes one by one would suffice.

That is the reason why people would want to read a file as a stream.

The reason why people want a stream as input for their data, is that they want to give the caller the opportunity to specify the source of their data: callers can provide a stream that reads from a file, but also a stream with data from the internet, or from a database, or from a textBox, the procedure does not care, as long as it can read the bytes one by one or sometimes per chunk of bytes:

using (Stream fileStream = File.Open(fileName)
{
    ProcessInputData(fileStream);
}

Or:

byte[] bytesToProcess = ...
using (Stream memoryStream = new MemoryStream(bytesToProcess))
{
    ProcessInputData(memoryStream);
}

Or:

string operatorInput = this.textBox1.Text;
using (Stream memoryStream = new MemoryStream(operatorInput))
{
    ProcessInputData(memoryStream);
}

Conclusioin

Methods use streams in their interface to indicate that they don't need all data in memory at once. One-by-one, or per chunk is enough. The caller is free to decide where the data comes from.

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116