2014-10-17 71 views
0

我已经工作超过转换的类C#(DataInputStream所DataOutputStream类),我已经完成了DataOutputStream类类,现在问题都坐在的InputStream类。C#BinaryReader在的readUTF从Java的DataOutputStream类

注意:我没有在C#中使用Encoding类的原因是因为Java中的DataInput/DataOutputStream使用自定义的UTF-8编码。

基本上,我有这样的代码:(C#),它采用了BinaryReader在

public String ReadUTF() 
    { 
     int utflen = this.ReadUnsignedShort(); 
     byte[] bytearr = null; 
     char[] chararr = null; 

     if(bytearr.Length < utflen) 
     { 
      bytearr = new byte[utflen * 2]; 
      chararr = new char[utflen * 2]; 
     } 

     int c, char2, char3; 
     int count = 0; 
     int chararr_count=0; 

     this.ReadFully(bytearr, 0, utflen); 

     while (count < utflen) { 
      c = (int) bytearr[count] & 0xff; 
      if (c > 127) break; 
      count++; 
      chararr[chararr_count++]=(char)c; 
     } 

     while (count < utflen) { 
      c = (int) bytearr[count] & 0xff; 
      switch (c >> 4) { 
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 
       /* 0xxxxxxx*/ 
       count++; 
       chararr[chararr_count++]=(char)c; 
       break; 
      case 12: case 13: 
       /* 110x xxxx 10xx xxxx*/ 
       count += 2; 
       if (count > utflen) 
        throw new Exception(
         "malformed input: partial character at end"); 
       char2 = (int) bytearr[count-1]; 
       if ((char2 & 0xC0) != 0x80) 
        throw new Exception(
         "malformed input around byte " + count); 
       chararr[chararr_count++]=(char)(((c & 0x1F) << 6) | 
               (char2 & 0x3F)); 
       break; 
      case 14: 
       /* 1110 xxxx 10xx xxxx 10xx xxxx */ 
       count += 3; 
       if (count > utflen) 
        throw new Exception(
         "malformed input: partial character at end"); 
       char2 = (int) bytearr[count-2]; 
       char3 = (int) bytearr[count-1]; 
       if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) 
        throw new Exception(
         "malformed input around byte " + (count-1)); 
       chararr[chararr_count++]=(char)(((c  & 0x0F) << 12) | 
               ((char2 & 0x3F) << 6) | 
               ((char3 & 0x3F) << 0)); 
       break; 
      default: 
       /* 10xx xxxx, 1111 xxxx */ 
       throw new Exception(
        "malformed input around byte " + count); 
      } 
     } 
     // The number of chars produced may be less than utflen 
     return new String(chararr, 0, chararr_count); 
    } 

这里是我的ReadUnsignedShort方法

public int ReadUnsignedShort() 
    { 
     int ch1 = BinaryReader.Read(); 
     int ch2 = BinaryReader.Read(); 
     if ((ch1 | ch2) < 0) 
     { 
      throw new EndOfStreamException(); // Temp- To be changed 
     } 
     return (ch1 << 8) + (ch2 << 0); 
    } 

这里的readFully方法将太已使用:

public void ReadFully(byte[] b, int off, int len) 
    { 
     if(len < 0) 
     { 
      throw new IndexOutOfRangeException(); 
     } 

     int n = 0; 
     while(n < len) 
     { 
      int count = ClientInput.Read(b, off + n, len - n); 
      if(count < 0) 
      { 
       throw new EndOfStreamException(); // Temp - to be changed 
      } 
      n += count; 
     } 
    } 

随着OutputStream的问题是我正在使用Write(int)而不是Write(byte)函数,但我不认为这是这种情况,无论是或者我必须是盲人。

如果你有兴趣在UTF串的发送方式,下面是它的C#转换:

public int WriteUTF(string str) 
    { 
     int strlen = str.Length; 
     int utflen = 0; 
     int c, count = 0; 

     for(int i = 0; i < strlen; i++) 
     { 
      c = str.ToCharArray()[i]; 
      if((c >= 0x0001) && (c <= 0x007F)) 
      { 
       utflen++; 
      } 
      else if(c > 0x07FF) 
      { 
       utflen += 3; 
      } 
      else 
      { 
       utflen += 2; 
      } 
     } 

     if(utflen > 65535) 
     { 
      throw new Exception("Encoded string is too long: " + utflen + " bytes"); 
     } 

     byte[] bytearr = null; 
     bytearr = new byte[(utflen*2) + 2]; 

     bytearr[count++] = (byte) (((uint)utflen >> 8) & 0xFF); 
     bytearr[count++] = (byte) (((uint)utflen >> 0) & 0xFF); 

     int x = 0; 
     for(x = 0; x < strlen; x++) 
     { 
      c = str.ToCharArray()[x]; 
      if (!((c >= 0x0001) && (c <= 0x007F))) break; 
      bytearr[count++] = (byte)c; 
     } 

     for(;x < strlen; x++) 
     { 
      c = str.ToCharArray()[x]; 
      if ((c >= 0x0001) && (c <= 0x007F)) 
      { 
       bytearr[count++] = (byte)c; 
      } 
      else if (c > 0x07FF) 
      { 
       bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); 
       bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F)); 
       bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); 
      } 
      else 
      { 
       bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); 
       bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); 
      } 
     } 
     ClientOutput.Write (bytearr, 0, utflen+2); 
     return utflen + 2; 
    } 

希望我提供足够的信息来获得一点帮助,阅读UTF价值观,这我的项目进展速度确实是一个障碍。

回答

-2

已经写Java的DataInputStream所DataOutputStream类的C#转换,你可以在这里收集它们。

https://bitbucket.org/CTucker1327/c-datastreams/src

构建这些类,你会传递的BinaryWriter或BinaryReader在进入构造函数。

要构建DataOutputStream类

DataOutputStream out = new DataOutputStream(new BinaryWriter(Stream)); 

要构建DataInputStream所

DataInptuStream in = new DataInputStream(new BinaryReader(Stream)); 
+0

如果这里的回答没有帮助,但是你能够自己解决问题,那么你会很高兴地跟随自己的问题和答案,以防其他人在未来遇到类似的情况。如果这里的任何回复都很有帮助,那么您应该评论如何以及为什么,当然还需要对任何有用的答案进行标记/提出投票以标识它们。谢谢! (你已经把源代码放在网上很好,但那是其他地方的,并且在任何情况下都不会明确地说明实际问题是(什么))。 – 2014-10-17 19:04:13

+1

该链接已经死了...你可以在其他地方分享代码吗? – 2017-01-19 08:00:53

1

如果我正确理解“问题”(例如,它是—,你说有“障碍”,但你没有解释“障碍”究竟是什么),你正试图在C#中实现读取代码并从流中写入文本。如果是这样,那么(我知道如果你是.NET新手,这并不明显)明确地处理文本编码是疯了。

BinaryReader和BinaryWriter有处理这个问题的方法。创建对象时,可以传递用于解释或创建文本二进制数据的Encoding实例(例如System.Text.Encoding.UTF8,System.Text.Encoding.Unicode等)。您可以使用BinaryReader.ReadChars(int)来读取文本,并使用BinaryWriter.Write(char [])来写入文本。

如果由于某些原因无法正常工作,至少可以使用Encoding实例来解释或创建一些文本的二进制数据。 Encoding.GetString(byte [])将二进制转换为文本,而Encoding.GetBytes(string)将文本转换为二进制。同样,使用特定的Encoding实例来处理您正在处理的实际文本编码。

+0

说我这样做的原因是因为'我在我的Java服务器使用DataOutputStream'类使用自定义的UTF-8加密,所以当我从服务器发送一个UTF字符串时,它使用它的编码不同于标准的UTF-8编码。这里的问题在于它没有正确读取数据,无论出于何种原因它不会返回字符串的值......或者甚至无法获得任何地方的信息。 http://msdn.microsoft.com/en-us/library/aa286366%28v=vs.60%29.aspx – Hobbyist 2014-10-17 03:38:02

+0

为了详细说明为什么我这样做,我一直在写的My Server Structure使用Java 'DataInputStream'和'DataOutputStream'类,我现在正在用C#编写一个客户端,它需要能够毫无问题地与服务器通信,考虑到Java类为UTF-8使用自定义编码,这就是为什么我要处理所有事情我自己尽可能的编码。 – Hobbyist 2014-10-17 03:41:04

+0

如果我正确理解Java实现,它与纯UTF8编码之间的唯一区别是指示剩余数据的字节数的双字节前缀。因此,只需将这两个字节作为Int16读取,然后使用该字节数来确定之后要读取的字节长度,然后将这些字节传递给Encoding.UTF8.GetString()。显然,你会做与编写字符串相反的。 – 2014-10-17 03:45:03