Optimising Splitting of Files - c#

Hi i currently use the following code to split a file into muliple 2mb smaller parts.
const int BUFFER_SIZE = 20 * 1024;
byte[] buffer = new byte[BUFFER_SIZE];
using (Stream input = File.OpenRead(inputFile)) {
int index = 0;
while (input.Position < input.Length) {
using (Stream output = File.Create(path)) {
int remaining = chunkSize, bytesRead;
while (remaining > 0 && (bytesRead = input.Read(buffer, 0,
Math.Min(remaining, BUFFER_SIZE))) > 0) {
output.Write(buffer, 0, bytesRead);
remaining -= bytesRead;
}
}
}
index++;
}
This works perfectly, and will split a 10mb file into 5 x 2mb files 0.part,2.part ect...
I would like to know how I would generate just part 3 again knowing the chunkSize always stays at 2mb. I can achieve this by wrapping in an if,else and evaluating index, but with a 1GB file this process can take a while to loop through. I'd like to understand this function more and how I can just get the part of the file I require?

input.Position property is settable. If you know that you need part 3, set Position to 2*chunkSize to skip the first two chunks, and do the innermost while loop once to copy from that position to the output:
int desiredChunkNumber = 3;
using (Stream input = File.OpenRead(inputFile)) {
input.Position = (desiredChunkNumber - 1) * chunkSize;
using (Stream output = File.Create(path)) {
int remaining = chunkSize, bytesRead;
while (remaining > 0 && (bytesRead = input.Read(buffer, 0,
Math.Min(remaining, BUFFER_SIZE))) > 0) {
output.Write(buffer, 0, bytesRead);
remaining -= bytesRead;
}
}
}

Related

tcp ip client read received data c#

TcpClient client = new(SERVER_IP, PORT_NO);
NetworkStream stream = client.GetStream();
stream.Write(WriteArry, 0, WriteArry.Length);
byte[] data = new byte[10];
int recivedbyte = stream.Read(data, 0, 10);
how can i check if Length of received data less than 10 wait more for Remaining data?
or Data to received more than once?
Thanks
byte[] data = new byte[10];
int read, remaining = data.Length;
while (remaining > 0 && (read =
stream.Read(data, data.Length - remaining, remaining)) > 0)
{
remaining -= read;
}
if (remaining != 0) throw new EndOfStreamException(); // EOF

C# - upload file by chunks - bad last chunk size

I am trying to upload large files to 3rd part service by chunks. But I have problem with last chunk. Last chunk would be always smaller then 5mb, but all chunks incl. the last have all the same size - 5mb
My code:
int chunkSize = 1024 * 1024 * 5;
using (Stream streamx = new FileStream(file.Path, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[chunkSize];
int bytesRead = 0;
long bytesToRead = streamx.Length;
while (bytesToRead > 0)
{
int n = streamx.Read(buffer, 0, chunkSize);
if (n == 0) break;
// do work on buffer...
// uploading chunk ....
var partRequest = HttpHelpers.InvokeHttpRequestStream
(
new Uri(endpointUri + "?partNumber=" + i + "&uploadId=" + UploadId),
"PUT",
partHeaders,
buffer
); // upload buffer
bytesRead += n;
bytesToRead -= n;
}
streamx.Dispose();
}
buffer is uploaded on 3rd party service.
Solved, someone posted updated code in comment, but after some seconds deleted this comment. But there was solution. I added this part after
if (n == 0)
this code, which resizes last chunk on the right size
// Let's resize the last incomplete buffer
if (n != buffer.Length)
Array.Resize(ref buffer, n);
Thank you all.
I post full working code:
int chunkSize = 1024 * 1024 * 5;
using (Stream streamx = new FileStream(file.Path, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[chunkSize];
int bytesRead = 0;
long bytesToRead = streamx.Length;
while (bytesToRead > 0)
{
int n = streamx.Read(buffer, 0, chunkSize);
if (n == 0) break;
// Let's resize the last incomplete buffer
if (n != buffer.Length)
Array.Resize(ref buffer, n);
// do work on buffer...
// uploading chunk ....
var partRequest = HttpHelpers.InvokeHttpRequestStream
(
new Uri(endpointUri + "?partNumber=" + i + "&uploadId=" + UploadId),
"PUT",
partHeaders,
buffer
); // upload buffer
bytesRead += n;
bytesToRead -= n;
}
}

NAudio WAV file Frequency to Decibels

I'm using NAudio to generate a WAV file. The Wav file contains environment noise (detected and recorded via mic).
I need to process this file to show average loudness (dB) against different frequency bands.
I read much about 1:3 Octave band analysis where the frequency windows are 31, 62, 125, 250, 500 Hz and so on. And we can have an average loudness against each window.
This is exactly what I want to do but HOW to achieve this seems confusing.
What I have done so far is (using NAudio tutorial) to read a WAV file and process it. Here is the code:
private void RenderFile()
{
using (WaveFileReader reader = new WaveFileReader(this.voiceRecorderState.ActiveFile))
{
this.samplesPerSecond = reader.WaveFormat.SampleRate;
SampleAggregator.NotificationCount = reader.WaveFormat.SampleRate/10;
//Sample rate is 44100
byte[] buffer = new byte[1024];
WaveBuffer waveBuffer = new WaveBuffer(buffer);
waveBuffer.ByteBufferCount = buffer.Length;
int bytesRead;
do
{
bytesRead = reader.Read(waveBuffer, 0, buffer.Length);
int samples = bytesRead / 2;
double sum = 0;
for (int sample = 0; sample < samples; sample++)
{
if (bytesRead > 0)
{
sampleAggregator.Add(waveBuffer.ShortBuffer[sample] / 32768f);
double sample1 = waveBuffer.ShortBuffer[sample] / 32768.0;
sum += (sample1 * sample1);
}
}
double rms = Math.Sqrt(sum / (SampleAggregator.NotificationCount));
double decibel = (double)(20 * Math.Log10(rms));
if (calculatedBCount == 0)
{
dBList.Add(decibel);
// System.Diagnostics.Debug.WriteLine(decibel.ToString() + " in dB");
}
} while (bytesRead > 0);
int totalSamples = (int)reader.Length / 2;
TotalWaveFormSamples = totalSamples / sampleAggregator.NotificationCount;
calculatedBCount++;
SelectAll();
//System.Diagnostics.Debug.WriteLine("Average Noise: " + avg.ToString() + " dB");
}
audioPlayer.LoadFile(this.voiceRecorderState.ActiveFile);
}
public int Read(byte[] buffer, int offset, int count)
{
if (waveBuffer == null || waveBuffer.MaxSize < count)
{
waveBuffer = new WaveBuffer(count);
}
int bytesRead = source.Read(waveBuffer, 0, count);
if (bytesRead > 0) bytesRead = count;
int frames = bytesRead / sizeof(float); // MRH: was count
float pitch = pitchDetector.DetectPitch(waveBuffer.FloatBuffer, frames);
PitchList.Add(pitch);
return frames * 4;
}
Using a 5 second WAV file, from above two methods, I get a list of Pitches and Decibels
The decibels list contains 484 values like:
-56.19945639
-55.13139952
-55.06947441
-56.70789076
-57.24140093
-55.98546603
-55.67407176
-55.53060998
-55.98480268
-54.85796943
-57.00735818
-55.64980974
-57.07235475
PitchList contains 62 values which include:
75.36621
247.631836
129.199219
75.36621
96.8994141
96.8994141
86.13281
75.36621
129.199219
107.666016
How can I use these results for identifying what is average loudness against 31Hz, 62Hz, 125Hz, 250Hz and so on.
Am I doing some wrong or everything wrong, maybe?
Please correct me if I am wrong but...I'm afraid You cannot convert HZ to DB because there is no relation between them.
Hz is a measure of frequency and Db is a measure of amplitude, sort like kilos to meters.

How to know that the stream has ended C#

I'm trying to recieve a tcp packet in C# but I don't know when can I stop reading from the stream.
Here's what I've tried:
for(int i = 0; i < stm.Length; i += chunkSize)
{
bb = new byte[chunkSize];
k = stm.Read(bb, 0, bb.Length);
ns.Write(bb, 0, k);
}
But it threw me an error about that the stream is not seekable.
So I've tried this:
int k = chunkSize;
while (k == chunkSize)
{
bb = new byte[chunkSize];
k = stm.Read(bb, 0, bb.Length);
ns.Write(bb, 0, k);
}
Is there anything to do?
Thanks :)
Here we go:
int read;
while((read = stm.Read(bb, 0, bb.Length)) > 0) {
// process "read"-many bytes from bb
ns.Write(bb, 0, read);
}
"read" will be non-positive at the end of the stream, and only at the end of the stream.
Or more simply (in 4.0):
stm.CopyTo(ns);
a binary reader is what you would require since it knows exactly how many bytes to read!
It prefixes the length of the bytes and so it knows how much to read!

C# Modulus Counting

Good Day,
I am writing an application where I'm downloading a file that is over 30MB. I am keeping track of how many bytes that have been currently been downloaded.
My question is:
I want to determine when I go past 1M, 2M, 3M and so forth.
My logic is:
int totalFileSave = 0;
...
...
int bytesRead = responseStream.Read(buffer, 0, 4096);
totalFileSave += bytesRead;
while (bytesRead > 0) {
// How do I test when I hit 1M, 2M, 3M and so forth...
bytesRead = responseStream.Read(buffer, 0, 4096);
totalFileSave += bytesRead;
}
private const int MEGABYTE = 1024 * 1024;
if ((bytesRead % MEGABYTE) == 0)
{
// Do something...
}
How about something like this:
private const int megaByte = 1024 * 1024;
private int current = 0;
while (bytesRead > 0)
{
bytesRead = responseStream.Read(buffer, 0, 4096);
totalFileSave += bytesRead;
int total = bytesRead / megaByte;
if (total > current)
{
current = total;
// you went up 1 M and are now at or greater than 'current'M
}
}

Categories

Resources