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);
}
}
Related
I am trying to read a binary file into a byte array.
I need to read the file in blocks of DWORDs (or 4 bytes) and store each block into a single element of the byte array. This is what I have achieved so far.
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
var block = new byte[4];
while (true)
{
byte[] temp = new byte[4];
fs.Read(temp, 0, 4);
uint read = (byte)BitConverter.ToUInt32(temp, 0);
block[0] = read???
}
}
However, converting the uint read to the element at block[0] is not working. I can't seem to find a way that doesn't produce errors.
Thanks for your input.
// read all bytes from file
var bytes = File.ReadAllBytes("data.dat");
// create an array of dwords by using 4 bytes in the file
var dwords = Enumerable.Range(0, bytes.Length / 4)
.Select(index => BitConverter.ToUInt32(bytes, index * 4))
.ToArray();
// down-casting to bytes
var dwordsAsBytes = dwords.Select(dw => (byte)dw).ToArray();
I need help to write hex data AB at adress 0x0156 in binary file in c#.
What i used BinaryWriter gives wrong data 00.
BinaryWriter bw = new BinaryWriter(File.OpenWrite(path));
bw.Write("AB");
bw.Dispose();
If you need to write it at address 0x156 you need to move there first using the Seek method. You also need to write a byte value rather than a string.
BinaryWriter bw = new BinaryWriter(File.OpenWrite(path));
bw.Seek(0x156,SeekOrigin.Begin);
bw.Write((byte)0xab);
bw.Dispose();
If the file does not exist, or is shorter than 343 bytes, it will be padded with 0 values up to the 342nd byte.
If you want to write a number of bytes starting from a particular location you could do something like this :
int StartLocation = 0x202;
int EndLocation = 0x30b;
byte ValueToWrite = 0xFF;
BinaryWriter bw = new BinaryWriter(File.OpenWrite(path));
bw.Seek(StartLocation,SeekOrigin.Begin);
for (int CurLocation = StartLocation; CurLocation <= EndLocation; CurLocation++)
bw.Write(ValueToWrite);
bw.Dispose();
Another way would be
int StartLocation = 0x202;
int EndLocation = 0x30b;
byte ValueToWrite = 0xFF;
byte [] ByteArray = new byte[EndLocation-StartLocation+1];
for (int i = 0; i < ByteArray.Length; i++)
ByteArray[i] = ValueToWrite;
BinaryWriter bw = new BinaryWriter(File.OpenWrite(path));
bw.Seek(StartLocation,SeekOrigin.Begin);
bw.Write(ByteArray);
bw.Dispose();
I am working with filestream read: https://msdn.microsoft.com/en-us/library/system.io.filestream.read%28v=vs.110%29.aspx
What I'm trying to do is read a large file in a loop a certain number of bytes at a time; not the whole file at once. The code example shows this for reading:
int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);
The definition of "bytes" is: "When this method returns, contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source."
I want to only read in 1 mb at a time so I do this:
using (FileStream fsInputFile = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read)) {
int intBytesToRead = 1024;
int intTotalBytesRead = 0;
int intInputFileByteLength = 0;
byte[] btInputBlock = new byte[intBytesToRead];
byte[] btOutputBlock = new byte[intBytesToRead];
intInputFileByteLength = (int)fsInputFile.Length;
while (intInputFileByteLength - 1 >= intTotalBytesRead)
{
if (intInputFileByteLength - intTotalBytesRead < intBytesToRead)
{
intBytesToRead = intInputFileByteLength - intTotalBytesRead;
}
// *** Problem is here ***
int n = fsInputFile.Read(btInputBlock, intTotalBytesRead, intBytesToRead);
intTotalBytesRead += n;
fsOutputFile.Write(btInputBlock, intTotalBytesRead - n, n);
}
fsOutputFile.Close(); }
Where the problem area is stated, btInputBlock works on the first cycle because it reads in 1024 bytes. But then on the second loop, it doesn't recycle this byte array. It instead tries to append the new 1024 bytes into btInputBlock. As far as I can tell, you can only specify the offset and length of the file you want to read and not the offset and length of btInputBlock. Is there a way to "re-use" the array that is being dumped into by Filestream.Read or should I find another solution?
Thanks.
P.S. The exception on the read is: "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."
Your code can be simplified somewhat
int num;
byte[] buffer = new byte[1024];
while ((num = fsInputFile.Read(buffer, 0, buffer.Length)) != 0)
{
//Do your work here
fsOutputFile.Write(buffer, 0, num);
}
Note that Read takes in the Array to fill, the offset (which is the offset of the array where the bytes should be placed, and the (max) number of bytes to read.
That's because you're incrementing intTotalBytesRead, which is an offset for the array, not for the filestream. In your case it should always be zero, which will overwrite previous byte data in the array, rather than append it at the end, using intTotalBytesRead.
int n = fsInputFile.Read(btInputBlock, intTotalBytesRead, intBytesToRead); //currently
int n = fsInputFile.Read(btInputBlock, 0, intBytesToRead); //should be
Filestream doesn't need an offset, every Read picks up where the last one left off.
See https://msdn.microsoft.com/en-us/library/system.io.filestream.read(v=vs.110).aspx
for details
Your Read call should be Read(btInputBlock, 0, intBytesToRead). The 2nd parameter is the offset into the array you want to start writing the bytes to. Similarly for Write you want Write(btInputBlock, 0, n) as the 2nd parameter is the offset in the array to start writing bytes from. Also you don't need to call Close as the using will clean up the FileStream for you.
using (FileStream fsInputFile = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read))
{
int intBytesToRead = 1024;
byte[] btInputBlock = new byte[intBytesToRead];
while (fsInputFile.Postion < fsInputFile.Length)
{
int n = fsInputFile.Read(btInputBlock, 0, intBytesToRead);
intTotalBytesRead += n;
fsOutputFile.Write(btInputBlock, 0, n);
}
}
I want to write something like this to a file:
FileStream output = new FileStream("test.bin", FileMode.Create, FileAccess.ReadWrite);
BinaryWriter binWtr = new BinaryWriter(output);
double [] a = new double [1000000]; //this array fill complete
for(int i = 0; i < 1000000; i++)
{
binWtr.Write(a[i]);
}
And unfortunately this code's process last very long!
(in this example about 10 seconds!)
The file format is binary.
How can I make that faster?
You should be able to speed up the process by converting your array of doubles to an array of bytes, and then write the bytes in one shot.
This answer shows how to do the conversion (the code below comes from that answer):
static byte[] GetBytes(double[] values) {
var result = new byte[values.Length * sizeof(double)];
Buffer.BlockCopy(values, 0, result, 0, result.Length);
return result;
}
With the array of bytes in hand, you can call Write that takes an array of bytes:
var byteBuf = GetBytes(a);
binWtr.Write(byteBuf);
You're writing the bytes 1 by 1, of course it's going to be slow.
You could do the writing in memory to an array and then write the array to disk all at once like this :
var arr = new double[1000000];
using(var strm = new MemoryStream())
using (var bw = new BinaryWriter(strm))
{
foreach(var d in arr)
{
bw.Write(d);
}
bw.Flush();
File.WriteAllBytes("myfile.bytes",strm.ToArray());
}
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);