Effective filestream
-
Hi, I was wondering if someone could give me some feedback on this method. My goal is to join several files into one and it works but is this an effective way of doing it? Is there something I can do to speed it up and make it more effective? I have tried playing with the buffer-size and increasing it makes it faster up to a certain point.
private void JoinFiles(string[] files, string outputFileName)
{
int buffSize = 1024;
byte[] buffer = new byte[buffSize];FileStream fsSave = new FileStream(outputFileName, FileMode.CreateNew); foreach (string file in files) { FileStream fs = new FileStream(file, FileMode.Open); long fileSize = fs.Length; while (fs.Position < fileSize) { if (fileSize - fs.Position > buffSize) { if (buffer.Length < buffSize) buffer = new byte\[buffSize\]; fs.Read(buffer, 0, buffSize); } else { buffer = new byte\[fileSize - fs.Position\]; fs.Read(buffer, 0, (int) (fileSize - fs.Position)); } fsSave.Write(buffer, 0, buffer.Length); } fs.Close(); } fsSave.Close();
}
http://johanmartensson.se - Home of MPEG4Watcher http://www.tinywebradio.com - Home of TinyWebRadio
-
Hi, I was wondering if someone could give me some feedback on this method. My goal is to join several files into one and it works but is this an effective way of doing it? Is there something I can do to speed it up and make it more effective? I have tried playing with the buffer-size and increasing it makes it faster up to a certain point.
private void JoinFiles(string[] files, string outputFileName)
{
int buffSize = 1024;
byte[] buffer = new byte[buffSize];FileStream fsSave = new FileStream(outputFileName, FileMode.CreateNew); foreach (string file in files) { FileStream fs = new FileStream(file, FileMode.Open); long fileSize = fs.Length; while (fs.Position < fileSize) { if (fileSize - fs.Position > buffSize) { if (buffer.Length < buffSize) buffer = new byte\[buffSize\]; fs.Read(buffer, 0, buffSize); } else { buffer = new byte\[fileSize - fs.Position\]; fs.Read(buffer, 0, (int) (fileSize - fs.Position)); } fsSave.Write(buffer, 0, buffer.Length); } fs.Close(); } fsSave.Close();
}
http://johanmartensson.se - Home of MPEG4Watcher http://www.tinywebradio.com - Home of TinyWebRadio
Hi Johan, I think without using Win32 to read/write the files at a lower level, what you've come up with is the best that .net can offer. The method below works in exactly the same way with a couple of minor changes for memory efficiency & some personal preferences - there's no need to create a new byte[] on each loop; just use the same buffer that you define at the top. I usually use a buffer size of 4KB as a balance between memory usage & file access operations. There's no need to calculate the buffer size to ensure you don't read past the end of the file - .Read returns the number of bytes actually read, even if you asked for more than is available. Finally, a personal preference, I like to use using() blocks with the FileStream just to guarantee the file is closed (the Dispose method on Stream is actually hidden, but it is there & calls close). Hope this helps, Rob
private void JoinFiles(string\[\] files, string outputFileName) { byte\[\] buffer = new byte\[0x1000\]; using (FileStream fsSave = new FileStream(outputFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { foreach (string file in files) { using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { while (true) { int count = fs.Read(buffer, 0, buffer.Length); if (count <= 0) break; fsSave.Write(buffer, 0, count); } } } } }
"An eye for an eye only ends up making the whole world blind"
-
Hi Johan, I think without using Win32 to read/write the files at a lower level, what you've come up with is the best that .net can offer. The method below works in exactly the same way with a couple of minor changes for memory efficiency & some personal preferences - there's no need to create a new byte[] on each loop; just use the same buffer that you define at the top. I usually use a buffer size of 4KB as a balance between memory usage & file access operations. There's no need to calculate the buffer size to ensure you don't read past the end of the file - .Read returns the number of bytes actually read, even if you asked for more than is available. Finally, a personal preference, I like to use using() blocks with the FileStream just to guarantee the file is closed (the Dispose method on Stream is actually hidden, but it is there & calls close). Hope this helps, Rob
private void JoinFiles(string\[\] files, string outputFileName) { byte\[\] buffer = new byte\[0x1000\]; using (FileStream fsSave = new FileStream(outputFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { foreach (string file in files) { using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { while (true) { int count = fs.Read(buffer, 0, buffer.Length); if (count <= 0) break; fsSave.Write(buffer, 0, count); } } } } }
"An eye for an eye only ends up making the whole world blind"
great. less code, a single buffer, my 5. :)
Luc Pattyn
:badger: :jig: :badger:
Have a look at my entry for the lean-and-mean competition; please provide comments, feedback, discussion, and don’t forget to vote for it! Thank you.
:jig: :badger: :jig:
-
Hi Johan, I think without using Win32 to read/write the files at a lower level, what you've come up with is the best that .net can offer. The method below works in exactly the same way with a couple of minor changes for memory efficiency & some personal preferences - there's no need to create a new byte[] on each loop; just use the same buffer that you define at the top. I usually use a buffer size of 4KB as a balance between memory usage & file access operations. There's no need to calculate the buffer size to ensure you don't read past the end of the file - .Read returns the number of bytes actually read, even if you asked for more than is available. Finally, a personal preference, I like to use using() blocks with the FileStream just to guarantee the file is closed (the Dispose method on Stream is actually hidden, but it is there & calls close). Hope this helps, Rob
private void JoinFiles(string\[\] files, string outputFileName) { byte\[\] buffer = new byte\[0x1000\]; using (FileStream fsSave = new FileStream(outputFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { foreach (string file in files) { using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { while (true) { int count = fs.Read(buffer, 0, buffer.Length); if (count <= 0) break; fsSave.Write(buffer, 0, count); } } } } }
"An eye for an eye only ends up making the whole world blind"
Thanks a lot for you answer, it's a much better looking code and it's easier to read. I just love getting feedback and watching how others write their code, there's a lot you can learn from that. So thank you again... :)
http://johanmartensson.se - Home of MPEG4Watcher http://www.tinywebradio.com - Home of TinyWebRadio