2011-02-11 29 views
3

我想创建一个包含int32,int16,单个值的内存流。使用二进制代码是无用的,所以我试图做字节数组。因为价值是不同的类型,我不知道如何正确地做到这一点。所以我尝试做这样的:从不同类型的数据字节数组的MemoryStream

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

你得到什么错误,从中读取流? – 2011-02-11 07:29:59

回答

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; 
} 
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(); 

请注意,我也为float值添加了一个计数。它不在您的示例数据中,但读取数据的方法需要它。

我确认数据可以正确读取。我用你的读者代码,写出来的结果:

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 
0

构建一个字节数组,这样是不行的,因为Int32Int16将被隐式转换为byte ,这不会发生浮点数,因此您的编译器错误。

最好的办法是写同样的方式您在使用,BinaryWriter(见其他答案)