1.你就是没有保存回去,就差一步了
Properties pps=System. getProperties()
pps.put("file.encoding","x-MacThai")
//设置完成后要将属性保存
System.setProperties(pps)
2.System.setProperty("file.encoding","x-MacThai")
3.运行时设置 java -D file.encoding=x-MacThai
java中编码:URLEncoder.encode(strUri,"utf-8")
java中解码码:URLDecoder.decode(strUri,"utf-8")
java编码和解码
流读取文件,具有转换编码功能的有:OutputStreamWriter和InputStreamReader,
构造器有如:
InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的 InputStreamReader。
OutputStreamWriter(OutputStream out, String charsetName)
创建使用指定字符集的 OutputStreamWriter。
处理字符串编码问题:
重新对获取的字符串进行编码:Byte[] bytes = str.getBytes(String encodeCharsetNam)
重新对bytes进行解码,创建新的字符串对象:str = new String(Byte[] bytes,String decodeCharsetName)
一般结合使用:str = new String(str.getBytes(String encodeCharsetName),String decodeCharsetName)
例如:resultName=new String(username.getBytes("ISO-8859-1"),"UTF-8")
还可以加入判断:
if(!Charset.forName("gbk").newEncoder().canEncode(str)){str = new Strin(str.getBytes("ISO-8859-1"),"UTF-8")}else{str = new String(str.getBytes("ISO-8859-1"),"gbk")}
处理请求参数传递编码问题:
java中编码:URLEncoder.encode(strUri,"utf-8")
java中解码码:URLDecoder.decode(strUri,"utf-8")
js中编码:encodeURIComponent(strUri)encodeURI(strUri)escape(str)
js中解码:decodeURIComponent(strUri)decodeURI(strUri)unescape(str)
补充概念:
URI组件:主机、端口、路径、查询参数、片段等。
URI组件分隔符::/?#&[]@,冒号用于分隔协议和主机,/用于分隔主机和 路径,?用于分隔路径和查询参数,&用于分隔多个查询参数等。
URI中的不安全字符或保留字符: ! * ‘ ( ) : @ &= + $ , / ? # [ ] 他们具有特殊作用,例如上面的分隔作用。
URI允许出现的字符:只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符,其他字符均需要经过编码之后才能出现在Url中,比如使用保留字符的原意,而不是特殊作用。
js向java/jsp的编码与解码:
js中编码:encodeURI(encodeURI(strUri))decodeURIComponent(decodeURIComponent(strUri))
java/jsp中解码: java.net.URLDecoder.decode(strUri,"UTF-8")
js中编码两次的问题:如果使用一次编码,在浏览器地址栏里,浏览器认为%是个转义字符,浏览器会把%与%之间的编码值,两位两位取出后进行解码。
然后再传递给处理页面,然后由处理页面进行再次解码,这样前面就缺少了一次编码过程,所以前面需要连续两次编码。
java内部是使用16bit的unicode编码(UTF-16)来表示字符串的,无论中文英文都是2字节; jni内部是使用UTF-8编码来表示字符串的,UTF-8是变长编码的unicode,一般ascii字符是1字节,中文是3字节; c/c++使用的是原始数据,ascii就是一个字节了,中文一般是GB2312编码,用两个字节来表示一个汉字。明确了概念, *** 作就比较清楚了。下面根据字符流的方向来分别说明一下
1、java -->c/c++
这种情况中,java调用的时候使用的是UTF-16编码的字符串,jvm把这个字符串传给jni,c/c++得到的输入是jstring,这个时候,可以利用jni提供的两种函数,一个是GetStringUTFChars,这个函数将得到一个UTF-8编码的字符串;另一个是 GetStringChars这个将得到UTF-16编码的字符串。无论那个函数,得到的字符串如果含有中文,都需要进一步转化成GB2312的编码。
2、c/c++ -->java
jni返回给java的字符串,c/c++首先应该负责把这个字符串变成UTF-8或者UTF-16格式,然后通过NewStringUTF或者NewString来把它封装成jstring,返回给java就可以了。
如果字符串中不含中文字符,只是标准的ascii码,那么使用GetStringUTFChars/NewStringUTF就可以搞定了,因为这种情况下,UTF-8编码和ascii编码是一致的,不需要转换。
但是如果字符串中有中文字符,那么在c/c++部分进行编码转换就是一个必须了。我们需要两个转换函数,一个是把UTF8/16的编码转成GB2312;一个是把GB2312转成UTF8/16。
这里要说明一下:Linux和win32都支持wchar,这个事实上就是宽度为16bit的unicode编码UTF16,所以,如果我们的 c/c++程序中完全使用wchar类型,那么理论上是不需要这种转换的。但是实际上,我们不可能完全用wchar来取代char的,所以就目前大多数应用而言,转换仍然是必须的。
二、一种转换方法
使用wide char类型来转换。
char* jstringToWindows( JNIEnv *env, jstring jstr )
{ //UTF8/16转换成gb2312
int length = (env)->GetStringLength(jstr )
const jchar* jcstr = (env)->GetStringChars(jstr, 0 )
char* rtn = (char*)malloc( length*2+1 )
int size = 0
size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL )
if( size <= 0 )
return NULL
(env)->ReleaseStringChars(jstr, jcstr )
rtn[size] = 0
return rtn
}
jstring WindowsTojstring( JNIEnv* env, const char* str )
{//gb2312转换成utf8/16
jstring rtn = 0
int slen = strlen(str)
unsigned short * buffer = 0
if( slen == 0 )
rtn = (env)->NewStringUTF(str )
else
{
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 )
buffer = (unsigned short *)malloc( length*2 + 1 )
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
rtn = (env)->NewString( (jchar*)buffer, length )
}
if( buffer )
free( buffer )
return rtn
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)