﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-自然-文章分类-错误汇总</title><link>http://www.blogjava.net/masen/category/54703.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 13 Oct 2015 15:15:32 GMT</lastBuildDate><pubDate>Tue, 13 Oct 2015 15:15:32 GMT</pubDate><ttl>60</ttl><item><title>乱码</title><link>http://www.blogjava.net/masen/articles/422795.html</link><dc:creator>Masen</dc:creator><author>Masen</author><pubDate>Fri, 06 Feb 2015 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/masen/articles/422795.html</guid><wfw:comment>http://www.blogjava.net/masen/comments/422795.html</wfw:comment><comments>http://www.blogjava.net/masen/articles/422795.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/masen/comments/commentRss/422795.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/masen/services/trackbacks/422795.html</trackback:ping><description><![CDATA[<span style="color: #666666; font-family: Tahoma; font-size: 12px; line-height: normal; background-color: #ffffff;">总结：只要把握文件本来的编码以及读取时的编码，乱码问题就不难解决。<br /><br />页面编码URF-8，get,post提交的编码由filter配置UTF-8，中间件如tomcat server.xml配置UTF-8，数据库UTF-8等。<br /><br />注意：Java 程序里 &#8220;字节&#8221; 到 &#8220;字符&#8221;时 （编码） 需要指定编码格式，<br />如 byte[]---String需要，file,xml文件-----到java里的String 也需要，此时未指定编码格式，会用默认gbk，如果指定了编码格式就会按照指定格式生成String字符。<br />如下lastE2.xml 指定了 按照UTF-8 来Reader生成字符串：<br /></span><div>new BufferedReader(new InputStreamReader(<br />				   new FileInputStream(PyFrontServiceImpl.class.getClassLoader().<br />						   getResource("py\\lastE2.xml").toURI().getPath()),"UTF-8"));</div><span style="color: #666666; font-family: Tahoma; font-size: 12px; line-height: normal; background-color: #ffffff;"><br />如下 &nbsp;</span>InputSource &nbsp; 未指定字节生成字符的编码格式，那么就是默认的。<br />InputSource source = new InputSource(new ByteArrayInputStream(resultStr.getBytes()));<span style="color: #666666; font-family: Tahoma; font-size: 12px; line-height: normal; background-color: #ffffff;"><br /></span>如果要指定可以增加： &nbsp;source.setEncoding("UTF-8"); 该方法对字符无效，因为字符流创建时会指定编码格式，或已经用默认的格式指定了。<br />并且，使用发现在tomcat下会出现以下错误： Parse Fatal Error at line 1 column 86: Invalid byte 2 of 2-byte UTF-8 sequence.<br />替换为字符流就OK：<br /><div><div>&nbsp;InputSource source = new InputSource(new StringReader(utf8String));// utf8String已经是UTF-8了，所以不用再次指定<br /></div></div>所以，在获取 字节 到生成 字符 过程中为了避免乱码，我们一定要制定编码格式，UTF-8。<br /><span style="color: #666666; font-family: Tahoma; font-size: 12px; line-height: normal; background-color: #ffffff;"><br />JVM编码和默认创建对象时的编码(转)：<br /><br /></span><table border="0" cellpadding="0" cellspacing="0" style="font-family: serif; width: 946px; height: 32px;"><tbody><tr><td style="vertical-align: top; width: 250px; text-align: center;"><br /><br /><ins id="aswift_1_expand" style="display: inline-table; border: none; height: 600px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 160px;"><ins id="aswift_1_anchor" style="display: block; border: none; height: 600px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 160px;"><iframe width="160" height="600" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" id="aswift_1" name="aswift_1" style="left: 0px; position: absolute; top: 0px;"></iframe></ins></ins><br /><br /></td><td style="vertical-align: top; width: 690px;"><small>如果在正體中文Windows中，</small><small>你使用以下的程式來讀取內含「測試」文字的檔案：<br /></small><pre style="color: #333333; border: 1px solid #777777; margin: 3px 25px; padding: 0px 10px; font-size: small; line-height: 17.5500011444092px; width: auto; font-family: 'Courier New', Courier, monospace; background-color: #eeeeee;">import java.io.*;<br />public class Main {<br />    public static void main(String[] args) throws Exception {<br />        BufferedReader reader = new BufferedReader(new FileReader(args[0]));<br />        System.out.println(reader.readLine());<br />        reader.close();<br />    }<br />}<br /></pre><span style="font-family: 'Courier New', Courier, monospace;"><br /></span><small>如果該檔案是使用MS950處理，那上面的程式可以正確讀出並顯示「測試」，如果文字檔案不是MS950，那就會顯示亂碼，例如，假設是UTF-8儲存「測試」的文字檔案：</small><small><br /></small><table border="0" cellpadding="2" cellspacing="2" style="width: 694.666687011719px;"><tbody><tr><td style="background-color: #000000;"><small style="font-family: 'Courier New', Courier, monospace;"><span style="color: #ffffff;">C:\workspace&gt;java Main sample.txt<br />皜祈岫<br /></span></small></td></tr></tbody></table><br /><small>有些API若不指定編碼，通常會使用JVM<span style="font-family: 'Courier New', Courier, monospace;">預設編碼，預設會與作業系統預設編碼相同，可以使用Charset.defaultCharset()取得預設編碼，</span>在API中，有許多API若不指定編碼，就會採用JVM預設編碼，像是<span style="font-family: 'Courier New', Courier, monospace;">String建構式、getBytes()方法或這邊看到的FileReader等。<br /><br />為了要正確讀取文字檔案，你要使用InputStreamReader，將讀入的位元組指定編碼進行字串轉換。例如：<br /></span></small><small><span style="font-family: 'Courier New', Courier, monospace;"></span></small><pre style="color: #333333; border: 1px solid #777777; margin: 3px 25px; padding: 0px 10px; font-size: small; line-height: 17.5500011444092px; width: auto; font-family: 'Courier New', Courier, monospace; background-color: #eeeeee;">import java.io.*;<br />public class Main {<br />    public static void main(String[] args) throws Exception {<br />        BufferedReader reader = new BufferedReader(<br />            new InputStreamReader(new FileInputStream(args[0]), "UTF-8"));<br />        System.out.println(reader.readLine());<br />        reader.close();<br />    }<br />}<br /></pre><br /><small>在正體中文Windows中，如下執行這個程式讀取UTF-8的文字檔案就可以正確顯示「測試」：</small><small><br /></small><table border="0" cellpadding="2" cellspacing="2" style="width: 694.666687011719px;"><tbody><tr><td style="background-color: #000000;"><small style="font-family: 'Courier New', Courier, monospace;"><span style="color: #ffffff;">C:\workspace&gt;java Main sample.txt<br />測試</span></small></td></tr></tbody></table><br /><small>在啟動JVM時，其實可以使用<span style="font-weight: bold;">-Dfile.encoding</span>指定JVM預設編碼，例如：</small><small><br /></small><table border="0" cellpadding="2" cellspacing="2" style="width: 694.666687011719px;"><tbody><tr><td style="background-color: #000000;"><small style="font-family: 'Courier New', Courier, monospace;"><span style="color: #ffffff;">C:\workspace&gt;java -Dfile.encoding=UTF-8 Main sample.txt<br />皜祈岫</span></small></td></tr></tbody></table><br /><small><span style="font-family: 'Courier New', Courier, monospace;">這次你看到了亂碼，這是因為System.out實際上是PrintStream實例，</span>會使用JVM預設編碼輸出文字，就上例而言，<span style="font-family: 'Courier New', Courier, monospace;">System.out使用UTF-8</span>輸出了文字，但你的Console顯示時是使用什麼編碼呢？<br /><br />程式都是正確的，問題是出在Console，這不單是發生在Windows的Console，也常有程式設計人員指著IDE中的Console問，為什麼看到亂碼或問號，請改變一下你的Console顯示編碼！要不然，在程式中改變一下<span style="font-family: 'Courier New', Courier, monospace;">System.out</span>的編碼處理：<br /></small><pre style="color: #333333; border: 1px solid #777777; margin: 3px 25px; padding: 0px 10px; font-size: small; line-height: 17.5500011444092px; width: auto; font-family: 'Courier New', Courier, monospace; background-color: #eeeeee;">import java.io.*;<br />public class Main {<br />    public static void main(String[] args) throws Exception {<br />	System.setOut(new PrintStream(System.out, true, "Big5"));<br />		<br />        BufferedReader reader = new BufferedReader(new FileReader(args[0]));<br />        System.out.println(reader.readLine());<br />        reader.close();<br />    }<br />}<br /></pre><small><br />在這個程式中，不指定<span style="font-family: 'Courier New', Courier, monospace;">FileReader</span>的讀取，所以會使用JVM預設編碼，而<span style="font-family: 'Courier New', Courier, monospace;">System.out</span>會用Big5，所以讀取UTF-8文字檔案時，若如下：</small><small><br /></small><table border="0" cellpadding="2" cellspacing="2" style="width: 694.666687011719px;"><tbody><tr><td style="background-color: #000000;"><small style="font-family: 'Courier New', Courier, monospace;"><span style="color: #ffffff;">C:\workspace&gt;java -Dfile.encoding=UTF-8 Main sample.txt<br />測試</span></small></td></tr></tbody></table><br /><small>由於</small><small>指定了</small><small>JVM預設編碼為UTF-8，所以程式中的<span style="font-family: 'Courier New', Courier, monospace;">FileReader</span>會用UTF-8讀取文字檔案，而輸出至主控台時，使用Big5編碼進行處理。<br /><br />使用某些API時，最好明確指定使用何種編碼，或者至少，要確認你的JVM預設編碼到底是什麼，以及API是否使用JVM預設編碼。<br /></small></td></tr></tbody></table><span style="color: #666666; font-family: Tahoma; font-size: 12px; line-height: normal; background-color: #ffffff;"><br /></span><img src ="http://www.blogjava.net/masen/aggbug/422795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/masen/" target="_blank">Masen</a> 2015-02-06 15:00 <a href="http://www.blogjava.net/masen/articles/422795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>