So I have this really simple code that reads a file and spits its data out in a hex viewer fashion. Here it is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace HexViewer
{
class Program
{
static void Main(string[] args)
{
BinaryReader br = new BinaryReader(new FileStream("C:\\dump.bin", FileMode.Open));
for (int i = 0; i < br.BaseStream.Length; i+= 16)
{
Console.Write(i.ToString("x") + ": ");
byte[] data = new byte[16];
br.Read(data, i, 16);
Console.WriteLine(BitConverter.ToString(data).Replace("-", " "));
}
Console.ReadLine();
}
}
}
The problem is that after the first iteration, when I do
br.Read(data, 16, 16);
The byte array is padded by 16 bytes, and then filled with data from 15th byte to 31st byte of the file. Because it can't fit 32 bytes into a 16 byte large array, it throws an exception. You can try this code with any file larger than 16 bytes. So, the question is, what is wrong with this code?
Just change br.Read(data, i, 16); to br.Read(data, 0, 16);
You are reading in a new block of data each time, so no need to use i for the data buffer.
Even better, change:
byte[] data = new byte[16];
br.Read(data, 0, 16);
To:
var data = br.ReadBytes(16);
Related
I am trying to write a console application that will take data as input and split it in to two
example: if i pass a value 0x00000000A0DB383E as input my output should be look like below:
var LowerValue = 0x00000000A0DB0000 (last 2 bytes 383E (index 14-17) replaced with 0000)
var UpperValue = 0x000000000000383E (middle 2 bytes A0DB (index 10-13) replaced with 0000)
So far i have tried below but dont know how to proceed further. Any help will be highly appreciated
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace SplitFunction
{
class Program
{
static void Main(string[] args)
{
byte[] rawValue = BitConverter.GetBytes(0x00000000A0DB383E);
SplitData(rawValue);
Console.ReadKey();
}
public static byte[] SplitDta(byte[] input)
{
byte[] lowerValues = new byte[8];
Array.Copy(input, 0, lowerValues, 4, 4);
foreach(var lowerValue in lowerValues)
Console.WriteLine(lowerValue);
return lowerValues;
}
}
}
Rather than copying & zeroing individual array elements, use masking to create new arrays directly. Something like this :
long input = 0x0000000A0DB383EL;
byte[] rawValue = BitConverter.GetBytes(input);
byte[] lowValue = BitConverter.GetBytes(input & 0x000000000000FFFF);
byte[] highValue = BitConverter.GetBytes(input & 0x00000000FFFF0000);
if you want the values in order high byte to low byte - then reverse them
byte[] rawValue = Array.Reverse(BitConverter.GetBytes(input));
byte[] lowValue = Array.Reverse(BitConverter.GetBytes(input & 0x000000000000FFFF));
byte[] highValue = Array.Reverse(BitConverter.GetBytes(input & 0x00000000FFFF0000));
if you simply want the long value rather than an array
long lowValue = input & 0x000000000000FFFF;
long highValue = input & 0x00000000FFFF0000;
I need to read bytes (converted from string to byte array and then sent to stream) from stream and stop reading as soon as I encounter specific sequence, in my case it's [13, 10, 13, 10] or "\r\n\r\n" if converted to string (ASCII).
Currently I have two versions of the same process:
1) Read from stream one byte at time and check EVERY byte if last 4 bytes of read sequence equals [13, 10, 13, 10] (note that I can't read and check every 4 bytes as sequence can be 7 bytes long, for example, so it'll read first 4 bytes and then stuck because only 3 of 4 bytes are available):
NetworkStream streamBrowser = tcpclientBrowser.GetStream();
byte[] data;
using (MemoryStream ms = new MemoryStream())
{
byte[] check = new byte[4] { 13, 10, 13, 10 };
byte[] buff = new byte[1];
do
{
streamBrowser.Read(buff, 0, 1);
ms.Write(buff, 0, 1);
data = ms.ToArray();
} while (!data.Skip(data.Length - 4).SequenceEqual(check));
}
2) Use StreamReader.ReadLine to read until "\r\n" and then read again to see if returned line is null, and then add to first returned string "\r\n", that way I'll get string that ends with "\r\n\r\n".
My question is - what method is preferable in terms of perfomance (if any, it may be that both are too slow and there are better way which I really would want to know)?
I am drunk, but maybe it will help:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ConsoleApp5
{
class Program
{
static void Main (string[] args)
{
var ms = new MemoryStream (new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
var sequence = new byte[] { 6, 7, 8 };
var buffer = new byte[1];
var queue = new Queue<byte> ();
int position = 0;
while (true)
{
int count = ms.Read (buffer, 0, 1);
if (count == 0) return;
queue.Enqueue (buffer[0]);
position++;
if (IsSequenceFound (queue, sequence))
{
Console.WriteLine ("Found sequence at position: " + (position - queue.Count));
return;
}
if (queue.Count == sequence.Length) queue.Dequeue ();
}
}
static bool IsSequenceFound (Queue<byte> queue, byte[] sequence)
{
return queue.SequenceEqual (sequence);
// normal for (int i ...) can be faster
}
}
}
I have a byte array consist of 32 bytes.
I want to read 4 bytes from index position 16 to 19.
How can i point binary reader to start reading from index 16.
I am trying these commands
byte[] trace ; // 32 byte array
using (FileStream s = File.OpenRead(filename))
using (BinaryReader r = new BinaryReader(s))
{
r.baseStream.Seek(position,SeekOrigin.Begin);
byte[] by = r.ReadBytes(4);
}
but i don't know what to put at position?
I think I got it (although your sample in the question is not very clear).
You have the byte array trace with 32 elements in it and you want to read 4 bytes starting with position 16.
Assuming that endianness is not a variable, you can use this to read the 4 bytes as an int value or byte array:
using(var memStream = new MemoryStream(trace))
{
//position the stream
using(var reader = new BinaryReader(memStream)
{
memStream.Seek(16, SeekOrigin.Begin);
var intValue = reader.ReadInt32();
memStream.Seek(16, SeekOrigin.Begin);
//now read a byte array
var byteArray = reader.ReadBytes(4);
}
}
I need to write a List of ints to a binary file of 4 bytes in length, so, I need to make sure that the binary file is correct, and I do the following:
using (FileStream fileStream = new FileStream(binaryFileName, FileMode.Create)) // destiny file directory.
{
using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
{
for (int i = 0; i < frameCodes.Count; i++)
{
binaryWriter.Write(frameCodes[i]);
binaryWriter.Write(4);
}
binaryWriter.Close();
}
}
at this line: binaryWriter.Write(4); I give the size, is that correct?
at this line "binaryWriter.Write(4);" I give the size, that's correct??
No, it's not correct. The line binaryWriter.Write(4); will write the integer 4 into the stream (e.g. something like 00000000 00000000 00000000 00000100).
This line is correct: binaryWriter.Write(frameCodes[i]);. It writes the integer frameCodes[i] into the stream. Since an integer requires 4 bytes, exactly 4 bytes will be written.
Of course, if your list contains X entries, then the resulting file will be of size 4*X.
AS PER MSDN
These two might help you. I know its not close to answer but will help you in getting the concept
using System;
public class Example
{
public static void Main()
{
int value = -16;
Byte[] bytes = BitConverter.GetBytes(value);
// Convert bytes back to Int32.
int intValue = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("{0} = {1}: {2}",
value, intValue,
value.Equals(intValue) ? "Round-trips" : "Does not round-trip");
// Convert bytes to UInt32.
uint uintValue = BitConverter.ToUInt32(bytes, 0);
Console.WriteLine("{0} = {1}: {2}", value, uintValue,
value.Equals(uintValue) ? "Round-trips" : "Does not round-trip");
}
}
byte[] bytes = { 0, 0, 0, 25 };
// If the system architecture is little-endian (that is, little end first),
// reverse the byte array.
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
int i = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("int: {0}", i);
My task is to decompress a packet(received) using zlib and then use an algoritm to make a picture from the data
The good news is that I have the code in C++,but the task is to do it in C#
C++
//Read the first values of the packet received
DWORD image[200 * 64] = {0}; //used for algoritm(width always = 200 and height always == 64)
int imgIndex = 0; //used for algoritm
unsigned char rawbytes_[131072] = {0}; //read below
unsigned char * rawbytes = rawbytes_; //destrination parameter for decompression(ptr)
compressed = r.Read<WORD>(); //the length of the compressed bytes(picture)
uncompressed = r.Read<WORD>(); //the length that should be after decompression
width = r.Read<WORD>(); //the width of the picture
height = r.Read<WORD>(); //the height of the picture
LPBYTE ptr = r.GetCurrentStream(); //the bytes(file that must be decompressed)
outLen = uncompressed; //copy the len into another variable
//Decompress
if(uncompress((Bytef*)rawbytes, &outLen, ptr, compressed) != Z_OK)
{
printf("Could not uncompress the image code.\n");
Disconnect();
return;
}
//Algoritm to make up the picture
// Loop through the data
for(int c = 0; c < (int)height; ++c)
{
for(int r = 0; r < (int)width; ++r)
{
imgIndex = (height - 1 - c) * width + r;
image[imgIndex] = 0xFF000000;
if(-((1 << (0xFF & (r & 0x80000007))) & rawbytes[((c * width + r) >> 3)]))
image[imgIndex] = 0xFFFFFFFF;
}
}
I'm trying to do this with zlib.NET ,but all demos have that code to decompress(C#)
private void decompressFile(string inFile, string outFile)
{
System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
try
{
CopyStream(inFileStream, outZStream);
}
finally
{
outZStream.Close();
outFileStream.Close();
inFileStream.Close();
}
}
public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}
My problem:I don't want to save the file after decompression,because I have to use the algoritm shown in the C++ code.
How to convert the byte[] array into a stream similiar to the one in the C# zlib code to decompress the data and then how to convert the stream back into byte array?
Also,How to change the zlib.NET code to NOT save files?
Just use MemoryStreams instead of FileStreams:
// Assuming inputData is a byte[]
MemoryStream input = new MemoryStream(inputData);
MemoryStream output = new MemoryStream();
Then you can use output.ToArray() afterwards to get a byte array out.
Note that it's generally better to use using statements instead of a single try/finally block - as otherwise if the first call to Close fails, the rest won't be made. You can nest them like this:
using (MemoryStream output = new MemoryStream())
using (Stream outZStream = new zlib.ZOutputStream(output))
using (Stream input = new MemoryStream(bytes))
{
CopyStream(inFileStream, outZStream);
return output.ToArray();
}
I just ran into this same issue.
For Completeness... (since this stumped me for several hours)
In the case of ZLib.Net you also have to call finish(), which usually happens during Close(), before you call return output.ToArray()
Otherwise you will get an empty/incomplete byte array from your memory stream, because the ZStream hasn't actually written all of the data yet:
public static void CompressData(byte[] inData, out byte[] outData)
{
using (MemoryStream outMemoryStream = new MemoryStream())
using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_DEFAULT_COMPRESSION))
using (Stream inMemoryStream = new MemoryStream(inData))
{
CopyStream(inMemoryStream, outZStream);
outZStream.finish();
outData = outMemoryStream.ToArray();
}
}
public static void DecompressData(byte[] inData, out byte[] outData)
{
using (MemoryStream outMemoryStream = new MemoryStream())
using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream))
using (Stream inMemoryStream = new MemoryStream(inData))
{
CopyStream(inMemoryStream, outZStream);
outZStream.finish();
outData = outMemoryStream.ToArray();
}
}
In this example I'm also using the zlib namespace:
using zlib;
Originally found in this thread:
ZLib decompression
I don't have enough points to vote up yet, so...
Thanks to Tim Greaves for the tip regarding finish before ToArray
And Jon Skeet for the tip regarding nesting the using statements for streams (which I like much better than try/finally)