我正在做我的android项目
Java代码:
String Tag="سیر";
String Value="";
try{
byte[] bytes = Tag.getBytes("UTF-16");
for(int i=0;i<bytes.length;i++){
Value=Value+String.valueOf(bytes[i])+",";
}
数组成员:数组成员是[-1,-2,51,6,-52,6,49,6]
。我检查了UTF-16的表格。它没有任何负数,而且我使用了一个将单词转换为UTF-16M的网站。它给了我“0633 06CC 0631”
十六进制。如果将此数字更改为十进制,您将看到以下内容:“157717401585”
。正如你看到的,这里没有负数!所以我的第一个问题是这些负数是什么?!
为什么要将单词转换为UTF-8或UTF-16?
我在做一个项目,这个项目有两个部分。第一部分是一个android应用程序,它向服务器发送关键词。这些话是客户发送的。我的客户使用(波斯语,فارسی ) 字符。第二部分是一个由C#制作的网络应用程序
问题:当我将这些单词发送到服务器时,它在一个“?”流上工作而不是正确的单词。我试过很多方法来解决这个问题,但他们都解决不了。之后,我决定自己将字符串的utf-16或utf-8发送到服务器,并将其转换为正确的单词。所以我选择了我在文章顶部描述的方法。
我的原始代码可靠吗?
是的。如果我使用英文字符,它的反应非常好。
我的原始代码是什么?
向服务器发送参数的Java代码:
protected String doInBackground(String...Urls){
String Data="";
HttpURLConnection urlConnection = null;
try{
URL myUrl=new URL("http://10.0.2.2:80/Urgence/SearchResault.aspx?Tag="+Tag);
urlConnection = (HttpURLConnection)myUrl.openConnection();
BufferedReader in = new BufferedReader (new InputStreamReader(urlConnection.getInputStream()));
String temp="";
// Data is used to store Server's Response
while((temp=in.readLine())!=null)
{
Data=Data+temp;
}
}
C#响应客户的代码:
string Tag = Request.QueryString["Tag"].ToString();
SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["conStr"].ToString();
SqlCommand cmd = new SqlCommand("FetchResaultByTag");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@NewsTag",Tag);
cmd.Connection = con;
SqlDataReader DR;
String Txt = "";
try
{
con.Open();
DR = cmd.ExecuteReader();
while (DR.Read())
{
Txt = Txt + DR.GetString(0) + "-" + DR.GetString(1) + "-" + DR.GetString(2) + "-" + DR.GetString(3) + "/";
}
//Response.Write(Txt);
con.Close();
}
catch (Exception ex)
{
con.Close();
Response.Write(ex.ToString());
}
*你觉得怎么样?你知道吗**
我的第一个问题是这些负数是什么?!
它们是文本的每个16位值中单个字节的有符号字节表示。在Java中,byte
类型是一个有符号值,类似于int
或long
,但只有8位信息。它可以表示从-128
到127
的任意值。当解释为Java字节时,它们仅为“负值”。
当然,作为UTF16编码文本中的字节,这种解释毫无意义。您应该仅将它们解释为UTF16编码文本。但是,负数是将UTF16编码的文本误解为有符号字节的普通数组的自然结果。
这类似于你做了类似
inti=-1;uint j=(uint)i
(在C#…中,Java本身没有无符号整数类型),然后询问为什么
j
不是负数,而是值4294967295
。嗯,j
是一种无符号数据类型;作为有符号的int
用于-1
的位模式与作为无符号的uint
用于4294967295
的位模式相同。
如果前面的段落对您没有意义,那么您需要自己阅读一些内容,以了解计算机如何存储数字,以及有符号和无符号数据类型之间的区别。
代码的输出数组,[-1,-2,51,6,-52,6,49,6]
,实际上是四个16位的值,以小数字节顺序排列:0xFEFF
,0x0633
,0x06CC
和0x0631
>。这些16位值中的每一个都代表一个Unicode代码点。
第一个用于UTF16编码文本的字节顺序标记。它是一个Unicode字符,专门用于指示UTF16编码中的字节是小端还是大端。另外三个是实际字符串中的字符。
但是,如果将字节分开并单独查看,如果将其视为有符号字节值,则大于
0x7F
(视为无符号字节值时)的任何值都将负数表示为有符号字节值。因此,0xFF
、0xFE
和0xCC
都显示为负数(每个都大于0x7F
)。但它们实际上仍然只是有效的16位Unicode代码点值的一半。
请注意,如果解释不正确,即使这些代码点值也可能显示为负值。在您的示例中,当解释为有符号的16位值时,只有一个会显示为负数-
0xFEFF
是-257
,即使Unicode码点实际上是十进制的65279
,但还有许多其他Unicode字符的值高于0x7FFFF
(十进制32767
),如果将其视为有符号的16位值,则显示为负数。
底线是计算机对数字一无所知。它们只有位,可以方便地分组成字节,还有各种各样的字大小。当你想知道这些位的含义时,你必须确保告诉计算机在向你显示这些位时要使用的正确、有用的表示法。如果你不这样做,那么你会得到一些其他的解释,这些位与它们的预期表示不匹配。垃圾进来,垃圾出去。
现在,假设你理解了以上所有内容,让我们考虑一下你更广泛的问题:
当我将这些单词发送到服务器时,它在一个“?”流上工作而不是正确的单词。我试过很多方法来解决这个问题,但他们都解决不了。
第一个要问自己的问题是“我是如何解读这些字节的?我如何向用户显示它们?"你没有分享任何在这方面实际相关的代码,但是你说过当你只使用拉丁字母(“英语字符”)时,它工作得很好。假设你也用UTF16测试了拉丁字母场景,那么这告诉我基本的输入/输出工作正常;你可能会出错的主要是字节顺序,但是如果发生这种情况,甚至拉丁字符也会被乱码。
所以
"????"最可能的解释是
您描述的是,您根本没有在可以显示波斯字符的上下文中查看文本。例如,使用控制台类将它们写入控制台窗口。控制台窗口中使用的字体不支持Unicode感知渲染,所以它不会显示波斯字符。在其他各种情况下也有类似的问题,包括例如。记事本(取决于使用的字体)和其他编辑器。
所以,对不起。所有这些都只是对你说“一切都很好,你可能只是没有使用正确的工具来验证你的结果。”
请注意,如果没有一个好的、最小的、完整的代码示例来可靠地再现您所看到的任何问题,就不可能确切地说发生了什么。如果在阅读和理解这个答案后,您仍然认为您的代码有问题,您需要花时间创建一个好的代码示例来清楚地演示实际问题。一行代码胜过一千个单词,一个合适的代码示例胜过黄金(混合几个完全不适用的隐喻:))。
我解决了。起初,我更改了java代码。我使用URLEncoder类将字符串转换为UTF-8。
新java代码:
try{
Tag=URLEncoder.encode(Tag,"UTF-8");
}
catch(Exception ex){
Log.d("Er>encodeing-Problem",ex.toString());
}
之后,我通过Http协议将其作为查询字符串发送
protected String doInBackground(String...Urls){
String Data="";
HttpURLConnection urlConnection = null;
try{
URL myUrl=new URL("http://10.0.2.2:80/Urgence/SearchResault.aspx?Tag="+Tag);
urlConnection = (HttpURLConnection)myUrl.openConnection();
BufferedReader in = new BufferedReader (new InputStreamReader(urlConnection.getInputStream()));
String temp="";
// Data is used to store Server's Response
while((temp=in.readLine())!=null)
{
Data=Data+temp;
}
最后我抓住了服务器并解码了它。
新的C#代码:
string Tag = Request.QueryString["Tag"].ToString();
SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["conStr"].ToString());
SqlCommand cmd = new SqlCommand("FetchResaultByTag");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@NewsTag", HttpUtility.UrlDecode(Tag));
cmd.Connection = con;
SqlDataReader DR;
String Txt = "";
try
{
con.Open();
DR = cmd.ExecuteReader();
while (DR.Read())
{
Txt = Txt + DR.GetString(0) + "-" + DR.GetString(1) + "-" + DR.GetString(2) + "-" + DR.GetString(3) + "/";
}
Response.Write(Txt);
con.Close();
}
catch (Exception ex)
{
con.Close();
Response.Write(ex.ToString());
}
我在将文本从UTF-8编码转换为UTF-8编码时遇到问题。这里有字节数组, 我正在将其转换为UTF-8字符串并返回字节数组, 据我所知,这是一个3字节的数组。正当但这是我得到的。 这是什么原因?据我所知,在UTF-8 Specials中,2391189组合被称为替换字符。 这也是一个更大问题的一部分。
我想知道是否有人能帮忙,我很难将UTF-8字符发布到SagePay。数据库是MySQL,带有数据库字符集utf8和数据库排序规则utf8_general_ci。数据库连接字符串使用useUnicode=true 所有发布到数据库的数据都存储为UTF-8,所有查询的数据都显示为UTF-8,但当字符串编码如下时: 然后发到SagePay,他们会收到一个来自国际字符所在位置的乱码字符串。如果字符串中不包
问题内容: 如何使用Android解码utf-8字符串?我尝试使用此命令,但输出与输入相同: 问题答案: 字符串不需要编码。它只是一个Unicode字符序列。 要将字符串转换为字节序列时需要进行 编码 。您选择的字符集(UTF-8,cp1255等)确定了Character-> Byte映射。请注意,字符不必转换为单个字节。在大多数字符集中,大多数Unicode字符都转换为至少两个字节。 字符串的编
问题内容: 最近,我们将应用程序从JDK 7迁移到了JDK8。更改之后,我们遇到了以下代码段的问题。 字节数组可能包含无效的UTF-8字节序列。UTF-8解码时,相同的字节数组在Java 7和Java 8上产生两个不同的字符串。 根据此SO帖子的答案,Java 8“修复”了Java7中的错误,并用替换字符串替换了无效的UTF-8字节序列,该字符串符合UTF-8规范。 但是我们想坚持使用Java 7
作为Python的新手,我已经花了很多时间。 我怎么能解码这样的URL: 到python 2.7中的这个: 返回的内容非常难看。 仍然没有解决办法,任何帮助都是感激的。
问题内容: 使用UTF-8编码创建字符串时存在不一致的地方。 运行此代码: 在Java 1.8.0_20(及更早版本)上,我们得到结果 在Java 1.7和1.6上,我们得到正确的结果: 您遇到此错误了吗?有没有解决方法? 对于Shift_JIS,JIS_X0212-1990,x-IBM300,x-IBM834,x-IBM942,x-IBM942C,x-JIS0208来说,这种不一致也很明显,但显