I welcome everyone, I made a method, it reads a file in parts, we input a stream, returns a variable number of blocks method, and also returns a KeyValuePair structure. I can’t figure out how to exit the method correctly using return. Thank you in advance.

public static KeyValuePair<int, byte[]> Read_Blok(Stream stream,out int count_blok) { int size = 1024 * 1024; int count_part = (int) (stream.Length /size );// количество частей int sizeLastPart = count_part - 1; // размер последней части byte[] buffer = new byte[size]; // размер буффера count_blok = 0; int count; for (int i = 0; i < count_part; i++) { if (i == count_part - 1) // когда достигаем последней части, последняя часть блока может быть меньше чем заданный буфер { buffer = new byte[sizeLastPart]; count=stream.Read(buffer, 0, buffer.Length); count_blok = count_blok + 1; return new KeyValuePair<int, byte[]>(count_blok,buffer); } else { count = stream.Read(buffer, 0, buffer.Length); count_blok = count_blok + 1; return new KeyValuePair<int, byte[]>(count_blok,buffer); stream.Position = i * buffer.Length;// сдвигаем позицию в потоке } } } 
  • and such a maneuver is not relevant here - 'return;' - Aqua
  • In the block else you need to go? - Aqua
  • @AquaGF That's exactly what I am thinking of, how can I return from the method with the KeyValuePair value <int, byte []> and with the value of the variable. That is, how can I exit without return. - Vladimr Vladimirovoch
  • and without return, you can not go out. The method has a returnable type, otherwise the project will not even compile - an error does not return all the code branches. For this, there is a trick using just return to force an exit from the loop. As I understand what you need - Aqua
  • @AquaGF yes you mean break; ? - Vladimr Vladimirovoch

2 answers 2

 public static IEnumerable<KeyValuePair<int, byte[]>> Read_Block(Stream stream) { const int SIZE_BLOCK = 1024 * 1024; // one megabyte int index = 0; while (stream.Position < stream.Length) { byte[] buffer = new byte[System.Math.Min(SIZE_BLOCK, stream.Length - stream.Position)]; stream.Read(buffer, 0, buffer.Length); yield return new KeyValuePair<int, byte[]>(index++, buffer); } } public static void Test() { using (FileStream fStream = new FileStream("file name", FileMode.Open)) { foreach (KeyValuePair<int, byte[]> block in Read_Block(fStream)) { // process block.Value } } } 

Line

 ... = new byte[System.Math.Min(SIZE_BLOCK, stream.Length - stream.Position)]; 

allocates memory for an array of one megabyte or, if there is less than the end of the stream, as many bytes as there are up to the end of the stream.

  • Understood, this is the same thing that is checked in my if, but shorter and more correct - Vladimr Vladimirovoch

I don’t know what’s wrong with the count_part calculation, but the code shouldn’t change its relevance and functionality, and @Igor rules the answer with a new variable calculation.

 public static KeyValuePair<int, byte[]> Read_Blok(Stream stream, out int count_blok) { int size = 1024 * 1024; int count_part = (int)(stream.Length / size);// количество частей int sizeLastPart = count_part - 1; // размер последней части byte[] buffer = new byte[size]; // размер буффера count_blok = 0; int count; for (int i = 0; i < count_part; i++) { if (i == count_part - 1) // когда достигаем последней части, последняя часть блока может быть меньше чем заданный буфер { buffer = new byte[sizeLastPart]; count = stream.Read (buffer, 0, buffer.Length); count_blok = count_blok + 1; } else { count = stream.Read (buffer, 0, buffer.Length); count_blok = count_blok + 1; stream.Position = i * buffer.Length;// сдвигаем позицию в потоке } } return new KeyValuePair<int, byte[]> (count_blok, buffer); }