I have a byte array . I need to remove the bytes at specific index and split the byte arrays. For example Say I have a byte array of length 1000 . And I need to remove the bytes from position 50 to 200 .So my expected result would be 2 byte arrays . One is 0-49 and another is 201-1000.
Is Array.RemoveAt the only way to remove the byte array with index?
Thanks in advance!
If speed is critical, you can create two new arrays and use Array.Copy() to copy the required bytes into them.
To make this easier to use, it might be more convenient to write a little extension method for arrays which extracts and returns a subset, like this (note: error handling omitted for brevity):
public static class ArrayExt
{
public static T[] Subset<T>(this T[] array, int start, int count)
{
T[] result = new T[count];
Array.Copy(array, start, result, 0, count);
return result;
}
}
Then you can use it like so (I have corrected the index from your example; you had it starting at 201, but it should have been 200):
var array1 = new byte[1000];
// ... populate array1 somehow, then extract subsets like so:
var array2 = array1.Subset( 0, 50);
var array3 = array1.Subset(200, 800);
// Now array2 and array3 are two byte arrays
// containing the required bytes.
This is probably the fastest you are likely to get.
You could use IEnumerable Take and Skip, for example
byte[] origin = new byte[200];
for(int i = 0; i < origin.Length; i++)
origin[i] = (byte)i;
byte[] first = origin.Take(50).ToArray();
byte[] second = origin.Skip(100).Take(50).ToArray();
Below code can be used to split the byte array, "index" starting index and "count" is the index count upto which index you want to split, here for your condition index=50 and count is 150;
List<byte> byteArray = array.ToList(); //array is the byte array
byteArray.RemoveRange(index, count);
Byte[] array1 = byteArray.ToArray(); //array1 is the resultant byte array
Cant you get the sub arrays like this?
byte[] array1 = array.ToList().GetRange(0, x1-1).ToArray();
byte[] array2 = array.ToList().GetRange(x2, array.Length- x2 - 1).ToArray();
where x1 and x2 is 50 and 200 in your example
Related
I have this List of integers { 20, 40 } and I want to get the length of the total number of bytes in the list
So since there are two integers, each integer is 4 bytes, therefore the total length of bytes in this case is 8.
If there was 3 integers the answer would be 12.
My idea was to loop through each integer and get the byte of the each integer using Bitconverter but I can't seem to append to the byte array.
var bytes = new byte[] { };
foreach (var num in nums)
{
bytes = BitConverter.GetBytes(num);
}
Then we would get the length of the bytes array but this method just does 1 value.
If you just want the number of bytes: sizeof(int) * nums.Count (or sizeof(int) * nums.Capacity if you want the size of the oversized backing array).
Assuming you want the data:
You can't use BitConverter to append bytes; you could copy each in turn, but honestly, that's not a good idea; you could loop applying offsets and using other APIs to write into the existing buffer, but - other tools exist; consider:
var nums = new List<int> { 20, 40 };
var arr = MemoryMarshal.Cast<int, byte>(CollectionsMarshal.AsSpan(nums)).ToArray();
// this is just a lazy way of showing the output
Console.WriteLine(BitConverter.ToString(arr));
Note that this is CPU-endian; if you need it to work identically on all CPUs, you'll need to use an endian-aware approach, for example BinaryPrimitives. For example:
byte[] arr = new byte[sizeof(int) * nums.Count];
var span = new Span<byte>(arr);
foreach (var num in nums)
{
BinaryPrimitives.WriteInt32BigEndian(span, num);
span = span.Slice(4);
}
Is it possible to control the index position in a byte[] array? In the following code I expect the return value of value1 enters in the first seven bytes in join and the return value of value2 enters in the 8 9 10 11 position sequentially. But this is not happening. The first seven bytes are lost because the index is in 0 position always. How to control the index position?
static void Main(string[] args)
{
byte[] join = new byte[15];
join = value1(); //seven byte enters.
join = value2(); //next four byte enters.
// 'join' should now have eleven bytes.
string a = Encoding.UTF8.GetString(join);
Console.WriteLine(a);
Console.ReadLine();
}
public static byte[] value1()
{
string first = "welcome";
byte[] f = Encoding.UTF8.GetBytes(first);
return f;// seven byte returning.
}
public static byte[] value2()
{
string second = "home";
byte[] s = Encoding.UTF8.GetBytes(second);
return s;//four byte returning.
}
I know the code can be reorganize using Array.Copy() or Buffer.BlockCopy(). But these two methods are time consuming if the code runs 100,000 times or more. I'm looking forward to avoid these two methods and get the return values directly inside join.
---Thanks
There is a way to do what you want, but you have to be careful. This GetBytes overload lets you specify the byte array into which the bytes will be copied, and the index at which they will be copied. So, in your example, it would look like this:
byte[] join = new byte[15];
int ix = 0;
ix = ix + Encoding.UTF8.GetBytes(first, 0, first.Length, join, ix);
ix = ix + Encoding.UTF8.GetBytes(second, 0, second.Length, join, ix);
string a = Encoding.UTF8.GetString(join, 0, ix);
The ix variable here keeps track of the total number of bytes that are encoded.
You have to be careful here to allocate enough bytes in your join array, and you have to keep track of the number of bytes encoded because with UTF-8 (and many other encodings) a single character could require multiple bytes.
You'll also want to see the GetString overload that lets you specify the starting position in the array and the number of bytes.
If you want to write methods that do this like your value1 and value2 methods, you'll have to pass the byte array and the array index to the methods. And those methods will have to return the number of bytes they encoded, or they'll have to add that value to the index and return the new index.
value1 and value2 methods returns a byte array, while you presumably want to append the values to the existing join array.
You can use Array.Copy (or Buffer.BlockCopy) to put the returned values inside join array :
var v1 = value1(); //seven byte returned.
var v2 = value2(); //next four byte returned.
var join = new byte[v1.Length + v2.Length];
// copy v1 at index 0 of join
Array.Copy(v1, 0, join, 0, v1.Length);
// copy v2 at index v1.Length of join
Array.Copy(v2, 0, join, v1.Length, v2.Length);
EDIT :
I did a small benchmark to test the performances of the proposed methods, and here's the result (with 6 millions of repetions for each method) :
Benchmark results (6000000 repetitions) :
JoinCodeUsingArrayCopy : 4076021 ticks (1304 ms)
JoinCodeUsingSetItems : 4873634 ticks (1559 ms)
JoinCodeUsingList : 8729925 ticks (2793 ms)
JoinCodeUsingBufferBlockCopy : 3665075 ticks (1172 ms)
Benchmark code here.
As you can see Array.Copy/Buffer.BlockCopy are the fastest methods, even if the method using list is not much much slower (we're talking about 1.5 second of difference on 6 million iterations after all).
Probably I would go for the list method because is the cleanest since it does not require to work directly with offsets/start indexes.
Instead of assigning items of your array, you are throwing away the new byte[15] and assigning it to new array. You can try using List<byte> first then convert it to an array:
var byteList = new List<byte>(15);
byteList.AddRange(value1());
byteList.AddRange(value2());
byte[] join = byteList.ToArray();
Another alternative is to create an extension method for your array, something like this:
public static void SetItems<T>(this T[] source, int startIndex, IEnumerable<T> items)
{
// I omitted the checks (index, length, null etc.) but you should add them
int i = startIndex;
foreach(var item in items)
source[i++] = item;
}
Then call it:
byte[] join = new byte[15];
join.SetItems(0, value1());
join.SetItems(4, value2());
This should be faster than first option because it doesn't create a list but it requires you to know the startIndex, in this case it shouldn't be a problem..
I am trying to convert a byte array to an int array ad then convert the byte array back to an int array.
For converting from byte array to int array I used this code:
int[] iArray = new int[someSize];
byte[] bArray = new byte[iArray.Length * sizeof(int)];
Buffer.BlockCopy(iArray, 0,bArray, 0, bArray.Length); // This code works correctly.
But when converting from the byte array to in int array, the values in the iArray2 array becomes false when the value in the iArray array is larger than 256 (may be it is overflow, I do not know.)
// What is the error in this code?.
int iArray2 = new int[someSize];
Buffer.BlockCopy(bArray, 0, iArray2, 0, iArray2.Length);
How can I convert from byte array to int array correctly?
Buffer.BlockCopy always deals in bytes, not array units.
Therefore, when you pass iArray2.Length in the second BlockCopy() call, you're copying that many bytes, which is one quarter of your actual array.
I'm looking for a smooth/fast way to retrieve every nth short in a byte array and copy it to a new array.
l = lowerbyte
u = upperbyte
My data is of the following form:
byte[] bytes= {a0l, a0u, b0l, b0u, c0l, ..., n0l, n0l, a1l, a1u, b1l, ..., nXl, nXu}
What I need is to get get n byte arrays of length X (e.g., a[0..X], b[0..X], ... or M[a..n][0..X])
I was thinking of the following two steps:
convert values to short (=> short[] shorts= { a0, b0, c0, ... n0, a1, .. nX})
by using something like
short[] shorts= new short[(int)(Math.Ceiling(bytes.Length / 2.0)];
Buffer.BlockCopy(bytes, 0, shorts, 0, bytes.Length);
retrieve every second value from shorts
I'm looking for some fast code here... something like blockcopy with skip
I am completely aware that I could use a loop - but maybe there's a better
solution to it as I need to do this task for 80MB/s...
convert it back to byte arrays (same same - using blockcopy)
byte[] arrayX = new byte[shorts.Length * 2];
Buffer.BlockCopy(shorts, 0, arrayX , 0, arrayX .Length);
Thank you so much!
I think you might as just well copy the bytes directly to the new byte array, having calculated the correct offset for each short.
Converting it all to a separate short array and back to a byte array is a waste of time IMO.
I have a multidimensional array
byte[,] matrix;
and i want copy in a 3 dimension array
byte[,,] 3dplan;
in this way
3dplan[,,0]=matrix
What is the fastest way to accomplish this task in c#?
You need to manually copy the elements in a nested loop; there is no faster way.
If you switch to a jagged array (byte[,][] or byte[][][]), you can insert the smaller array as-is into a slot in the larger array (although they will both refer to the same array instance and will pick up changes)
You can copy 2d array into 3d array with Buffer.BlockCopy:
var _3dplan = new int[2, 2, 2];
var _2dplan = new int[2, 2] { { 1, 1 }, { 1, 1 } };
var index = 0;
var size = _2dplan.Length * sizeof(int);
Buffer.BlockCopy(_2dplan, 0, _3dplan, index * size, size);