NSNonLossyASCIIStringEncoding等效于Android
我需要将一些聊天代码从iOS移植到Android。 在将聊天消息发送到套接字之前,iOS代码使用NSNonLossyASCIIStringEncoding
类作为NSString :: dataUsingEncoding的参数。
你会怎么做在Android? 同样的问题关于相反的解码。
如果不这样做,例如,换行符会在另一个移动设备上收到的消息中消失。
iOS上的代码:
NSData *data1 = [myStringTosend dataUsingEncoding:NSNonLossyASCIIStringEncoding]; NSString *goodValue = [[[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding] autorelease];
并解码:
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
到目前为止(而不是正确的),在Android端编码:
OutputStream os = socket.getOutputStream(); os.write(request.getBytes("UTF-8")); os.flush();
并解码:
while ((bytesRead = is.read(buffer, 0, BUFFER_SIZE)) >= 0) { if (bytesRead > 0) response.append(new String(buffer, 0, bytesRead, "UTF-8")); if (bytesRead < BUFFER_SIZE) break; }
@portforwardpodcast是绝对正确的,你应该尽可能避免使用ASCII编码你的utf8,而是设置你的堆栈直接处理/存储utf8。 也就是说,如果你没有能力改变行为,下面的代码可能会有所帮助。
虽然没有公布关于NSNonLossyASCIIStringEncoding
如何工作的解释, NSNonLossyASCIIStringEncoding
它的输出如下所示:
- 扩展ASCII范围中的字节(十进制值128 – 255)使用八进制编码(例如,带有十进制值241 – >
\361
ñ
) - 非ASCII代码点使用hex编码在两个字节块中转义(例如,😥占用32位,十进制值为128549 – >
\ud83d\ude25
)
所以编码:
public static String encodeToNonLossyAscii(String original) { Charset asciiCharset = Charset.forName("US-ASCII"); if (asciiCharset.newEncoder().canEncode(original)) { return original; } StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < original.length(); i++) { char c = original.charAt(i); if (c < 128) { stringBuffer.append(c); } else if (c < 256) { String octal = Integer.toOctalString(c); stringBuffer.append("\\"); stringBuffer.append(octal); } else { String hex = Integer.toHexString(c); stringBuffer.append("\\u"); stringBuffer.append(hex); } } return stringBuffer.toString(); }
并解码(这可以通过解锁两种types的编码,而不是两个单独的通行证更有效):
private static final Pattern UNICODE_HEX_PATTERN = Pattern.compile("\\\\u([0-9A-Fa-f]{4})"); private static final Pattern UNICODE_OCT_PATTERN = Pattern.compile("\\\\([0-7]{3})"); public static String decodeFromNonLossyAscii(String original) { Matcher matcher = UNICODE_HEX_PATTERN.matcher(original); StringBuffer charBuffer = new StringBuffer(original.length()); while (matcher.find()) { String match = matcher.group(1); char unicodeChar = (char) Integer.parseInt(match, 16); matcher.appendReplacement(charBuffer, Character.toString(unicodeChar)); } matcher.appendTail(charBuffer); String parsedUnicode = charBuffer.toString(); matcher = UNICODE_OCT_PATTERN.matcher(parsedUnicode); charBuffer = new StringBuffer(parsedUnicode.length()); while (matcher.find()) { String match = matcher.group(1); char unicodeChar = (char) Integer.parseInt(match, 8); matcher.appendReplacement(charBuffer, Character.toString(unicodeChar)); } matcher.appendTail(charBuffer); return charBuffer.toString(); }
不要使用NSNonLossyASCIIStringEncoding,使用utf-8编码。 我刚刚在ios + android + java spring后端解决了这个问题,花了我整整4天的时间才弄清楚了。 Android无法显示表情符号,但是这使得我几乎所有(或所有不确定的)语言都能提供全面的字符支持。 以下是帮助我的文章:
必须阅读: http : //blog.manbolo.com/2012/10/29/supporting-new-emojis-on-ios-6 http://blog.manbolo.com/2011/12/12/supporting-ios- 5-新表情符号编码
查看DB中string的hex字节: 如何查看存储在MySQL列中的原始字节?
有关如何设置MySQL的详细信息: http : //technovergence-en.blogspot.com/2012/03/mysql-from-utf8-to-utf8mb4.html
深入的utf8- http://www.unicode.org/faq/utf_bom.html#utf8-4 FAQ
有关与符号的区别的详细信息:\ ud83d \ udc7d和内存中的hex值:0xF09F91BD http://en.wikipedia.org/wiki/UTF-8#Description
使用它来复制和粘贴字符来查看真正的hex字节值(适用于emojis): http : //perishablepress.com/tools/utf8-hex/index.php
获取Spring在Url中支持utf8(用于获取参数) http://forum.springsource.org/showthread.php?93728-RequestParam-doesn-t-seem-to-be-decoded 获取参数编码 http:// forum。 springsource.org/showthread.php?112181-Unable-to-Override-the-Spring-MVC-URL-decoding-which-uses-default-quot-ISO-8859-1-quot
我的答案代码相当于Android的IOS NSNonLossyASCIIStringEncoding。
在你的泥沼放在低于depandancy。
compile 'org.apache.commons:commons-lang3:3.4'
然后把方法放到你的Utils类中就像这样
public static String encode(String s) { return StringEscapeUtils.escapeJava(s); } public static String decode(String s) { return StringEscapeUtils.unescapeJava(s); }
那么就简单的调用这个方法,在这里你要对string进行编码或者解码String就像这样
//for encode String stencode = Utils.encode("mystring"); //for decode String stdecode = Utils.decode("mystring")