我想创建一个包含int32,int16,单值的内存流。使用二进制文件是没用的,所以我试图创建字节数组。因为值是不同的类型,我不知道如何正确地做到这一点。所以我尝试这样做:
byte[] tab = new byte[]{2,0,0,0,3,0,3,0}
- 2是int32(四个字节),另外两个3是int16(两个字节)
工作正常,但是当我想添加一些单个值时,它会产生错误。我不能这样做:
byte[] tab = new byte[]{2,0,0,0,3,0,3,0,4.4f,5.6f}
我必须有正确格式的流,因为该方法将读取该流:
short[] rawData;
float[] modulusData;
public void rawData(Stream s)
{
BinaryReader br = new BinaryReader(s);
int dataCount = br.ReadInt32();
if (dataCount > 0)
{
rawData = new short[dataCount];
for (int i = 0; i < dataCount; i++)
rawData[i] = br.ReadInt16();
}
else
rawData = new short[0];
dataCount = br.ReadInt32();
if (dataCount > 0)
{
modulusData = new float[dataCount];
for (int i = 0; i < dataCount; i++)
modulusData[i] = br.ReadSingle();
}
else
modulusData = new float[0];
}
任何人都知道如何做到这一点?
答案 0 :(得分:5)
与原始陈述相反,BinaryWriter
完全正是您想要的。这就是它的设计目标。特别是,如果您稍后要使用BinaryReader
,那将非常合适。
你没有说明为什么你不想使用它,但它确实是你应该使用的:
using (MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(2);
writer.Write((short) 3);
writer.Write((short) 3);
writer.Write(4.4f);
writer.Write(5.6f);
}
byte[] bytes = stream.ToArray();
}
这将生成一个包含以下数据的字节数组:
[Int32 ] [Int16] [Int16] [Single ] [Single ]
02 00 00 00 03 00 03 00 CD CC 8C 40 33 33 B3 40
有一点需要注意 - 您的写描述会写下这些值:
- Int32
- Int16
- Int16
- Single
- Single
...但您的阅读代码将显示为:
- Int32 (value 2)
- Int16
- Int16
- Int32 (this wasn't written - so you're reading data from the first Single!)
- ???
换句话说,如果您之前使用BinaryWriter
的尝试失败,因为它们看起来像我的初始代码,那是因为您忘记了
writer.Write(2);
写入Int16值后,说明存在多少单值。
请注意,如果您不需要将值作为字节数组,则无需调用ToArray
- 只需返回流(不会丢弃它)。但是,在阅读之前,您需要“回放”它。例如:
public Stream GetData()
{
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream); // Don't close at the end!
writer.Write(2);
writer.Write((short) 3);
writer.Write((short) 3);
writer.Write(2); // Extra count for the Single values
writer.Write(4.4f);
writer.Write(5.6f);
writer.Flush(); // May not be required...
stream.Position = 0; // Rewind so stream can be read again
return stream;
}
答案 1 :(得分:3)
BinaryWriter根本没用。只需创建一个内存流并写入它:
MemoryStream m = new MemoryStream();
using (BinaryWriter writer = new BinaryWriter(m)) {
writer.Write(2); // count
writer.Write((short)3);
writer.Write((short)3);
writer.Write(2); // count
writer.Write(4.4f);
writer.Write(5.6f);
}
byte[] tab = m.ToArray();
请注意,我还为浮点值添加了一个计数。它不在您的示例数据中,但读取数据的方法需要它。
我确认可以正确读取数据。我使用了你的读者代码,并写出了结果:
Console.WriteLine(rawData.Length);
foreach (short x in rawData) Console.WriteLine(x);
Console.WriteLine(modulusData.Length);
foreach (float f in modulusData) Console.WriteLine(f);
输出:
2
3
3
2
4,4
5,6
答案 2 :(得分:0)
构造像这样的字节数组不起作用,因为Int32
和Int16
将被隐式转换为byte
,这对于浮点数不会发生,因此你的编译器错误。
最好的方法是使用与BinaryWriter
相同的方式写入流:{{1}}(参见其他答案)