中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
【Java 基礎專題】編碼與亂碼(04)---輸出時的編碼與亂碼 - Java - 拼吾愛...
 【Java 基礎專題】編碼與亂碼(04)---輸出時的編碼與亂碼
cobra - 2010-2-22 23:58:00
上一篇:【Java 基礎專題】編碼與亂碼(03)----String的toCharArray()方法測試
  1. package example.encoding;

  2. import java.io.BufferedWriter;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.FileWriter;
  7. import java.io.IOException;
  8. import java.io.OutputStreamWriter;
  9. import java.io.PrintWriter;
  10. import java.io.UnsupportedEncodingException;
  11. import java.io.Writer;
  12. import java.nio.charset.Charset;
  13. import java.util.Iterator;
  14. import java.util.Set;
  15. import java.util.SortedMap;

  16. /** *//**
  17. * <pre>
  18. * The Class IOEncodeTest is a tester class for java encoding. Mainnaly contains
  19. * two parts:
  20. *  1.Test written by FileWriter, with or without given character encoding value
  21. *  2.Test written by OutputStreamWriter, with or without given character encoding value
  22. * </pre>
  23. *
  24. * @author Paul Lin
  25. * @version 1.0
  26. */
  27. public class OutputEncodingTest {

  28.     private static String word = "Hello world! 中國";

  29.     private static final String ENCODING_EN = "ISO-8859-1";

  30.     private static final String ENCODING_CN = "GB2312";

  31.     private static final String ENCODING_UTF = "UTF-8";

  32.     private static final String DEFAULT_SYSTEM_ENCODING = System
  33.             .getProperty("file.encoding");

  34.     /** *//**
  35.     * The main method.
  36.     *
  37.     * @param args the arguments
  38.     */
  39.     public static void main(String args[]) {
  40.         OutputEncodingTest tester = new OutputEncodingTest();
  41.         tester.testFileWriter();
  42.         tester.testOutputStreamWriter();
  43.     }

  44.     /** *//**
  45.     * Test file writer.
  46.     */
  47.     public void testFileWriter() {
  48.         // Create test result folder
  49.         String resultFolder = createResultFolder(System
  50.                 .getProperty("user.language"), getBasePath());
  51.         // With default platform encoding
  52.         writeByFileWriter(word, resultFolder);
  53.         // With given system file.encoding property
  54.         writeByFileWriter(word, ENCODING_EN, resultFolder);
  55.         writeByFileWriter(word, ENCODING_CN, resultFolder);
  56.         writeByFileWriter(word, ENCODING_UTF, resultFolder);
  57.     }

  58.     /** *//**
  59.     * Test output stream writer.
  60.     */
  61.     public void testOutputStreamWriter() {
  62.         // Create test result folder
  63.         String resultFolder = createResultFolder(System
  64.                 .getProperty("user.language"), getBasePath());
  65.         // With default platform encoding
  66.         writeByOutputStreamWriter(word, resultFolder);
  67.         // With given system file.encoding property
  68.         writeByOutputStreamWriter(word, ENCODING_EN, resultFolder);
  69.         writeByOutputStreamWriter(word, ENCODING_CN, resultFolder);
  70.         writeByOutputStreamWriter(word, ENCODING_UTF, resultFolder);
  71.     }

  72.     /** *//**
  73.     * Prints the available charset.
  74.     */
  75.     public void printAvailableCharset() {
  76.         SortedMap<String, Charset> charsets = Charset.availableCharsets();
  77.         Set<String> charsetKeys = charsets.keySet();
  78.         System.out.println("\n<<<< Canonical name -- Display name -- "
  79.                 + " Can encode >>>>\n");

  80.         Iterator<String> i = charsetKeys.iterator();
  81.         while (i.hasNext()) {
  82.             String key = (String) i.next();
  83.             Charset charset = (Charset) charsets.get(key);
  84.             String displayName = charset.displayName();
  85.             boolean canEncode = charset.canEncode();
  86.             System.out.println(key + " - " + displayName + " - " + canEncode);
  87.         }
  88.     }

  89.     /** *//**
  90.     * Write by file writer.
  91.     *
  92.     * @param content the content
  93.     */
  94.     private void writeByFileWriter(String content, String destination) {
  95.         String defaultEncoding = System.getProperty("file.encoding");
  96.         System.out.println("Using default system encoding: " + defaultEncoding);
  97.         writeByFileWriter(content, defaultEncoding, destination);
  98.     }

  99.     /** *//**
  100.     * Write by file writer.
  101.     *
  102.     * @param content the content
  103.     * @param encoding the encoding
  104.     */
  105.     private void writeByFileWriter(String content, String encoding,
  106.             String destination) {
  107.         printDebugInformation("FileWriter", encoding, content);

  108.         // Get system default encoding
  109.         String defaultEncoding = System.getProperty("file.encoding");

  110.         // Reset underlying platform character encoding
  111.         if (!defaultEncoding.equalsIgnoreCase(encoding)) {
  112.             System.setProperty("file.encoding", encoding);
  113.         }

  114.         // Save as file with given encoding value
  115.         String file = returnFileName(destination, "write_by_filewriter_",
  116.                 encoding, ".txt");
  117.         try {
  118.             Writer writer = new BufferedWriter(new FileWriter(file));
  119.             writer.write(content);
  120.             writer.flush();
  121.             writer.close();
  122.         } catch (IOException ioe) {
  123.             ioe.printStackTrace();
  124.         }

  125.         // Reset character encoding to system default value
  126.         resetDefaultSystemEncoding();
  127.     }

  128.     /** *//**
  129.     * Write by output stream writer.
  130.     *
  131.     * @param content the content
  132.     */
  133.     private void writeByOutputStreamWriter(String content, String destination) {
  134.         String defaultEncoding = System.getProperty("file.encoding");
  135.         System.out.println("Using default system encoding: " + defaultEncoding);
  136.         writeByOutputStreamWriter(content, defaultEncoding, destination);
  137.     }

  138.     /** *//**
  139.     * Write by output stream writer.
  140.     *
  141.     * @param content the content
  142.     * @param encoding the encoding
  143.     */
  144.     private void writeByOutputStreamWriter(String content, String encoding,
  145.             String destination) {
  146.         printDebugInformation("OutputStreamWriter", encoding, content);

  147.         // Save as file with given encoding value
  148.         String file = returnFileName(destination,
  149.                 "write_by_outputStreamWriter_", encoding, ".txt");
  150.         try {
  151.             Writer writer = new PrintWriter(
  152.                     new BufferedWriter(new OutputStreamWriter(
  153.                             new FileOutputStream(file), encoding)));
  154.             writer.write(content);
  155.             writer.flush();
  156.             writer.close();
  157.         } catch (FileNotFoundException fnfe) {
  158.             fnfe.printStackTrace();
  159.         } catch (UnsupportedEncodingException uee) {
  160.             uee.printStackTrace();
  161.         } catch (IOException ioe) {
  162.             ioe.printStackTrace();
  163.         }

  164.         // Reset character encoding to system default value
  165.         resetDefaultSystemEncoding();
  166.     }

  167.     /** *//**
  168.     * Gets the base path.
  169.     *
  170.     * @return the base path
  171.     */
  172.     private String getBasePath() {
  173.         StringBuffer finalPath = new StringBuffer();
  174.         String dir = System.getProperty("user.dir");

  175.         finalPath.append(dir);
  176.         finalPath.append((dir.endsWith("\\") || dir.endsWith("/")) ? "" : "/");
  177.         finalPath.append("src").append("/");
  178.         finalPath.append("example").append("/");
  179.         finalPath.append("encoding").append("/");
  180.         return finalPath.toString();
  181.     }

  182.     /** *//**
  183.     * Return file name.
  184.     *
  185.     * @param basePath the base path
  186.     * @param prefix the prefix
  187.     * @param content the content
  188.     * @param subfix the subfix
  189.     *
  190.     * @return the string
  191.     */
  192.     private String returnFileName(String basePath, String prefix,
  193.             String content, String subfix) {
  194.         StringBuffer name = new StringBuffer(basePath);
  195.         if ((!basePath.endsWith("\\") && (!basePath.endsWith("/")))) {
  196.             name.append("/");
  197.         }
  198.         name.append(prefix);
  199.         name.append(content);
  200.         name.append(subfix);
  201.         return name.toString();
  202.     }

  203.     /** *//**
  204.     * Creates the result folder.
  205.     *
  206.     * @param platform the platform
  207.     * @param fullPath the full path
  208.     *
  209.     * @return the string
  210.     */
  211.     private String createResultFolder(String platform, String fullPath) {
  212.         StringBuffer resultFolder = new StringBuffer();

  213.         if (fullPath.endsWith("\\") || fullPath.endsWith("/")) {
  214.             resultFolder.append(fullPath);
  215.         } else {
  216.             resultFolder.append(fullPath).append("/");
  217.         }
  218.         resultFolder.append("Test_Result_Of_").append(platform);

  219.         File file = new File(resultFolder.toString());
  220.         if (!file.exists()) {
  221.             file = new File(resultFolder.toString());
  222.             file.mkdir();
  223.             return resultFolder.toString();
  224.         } else {
  225.             return file.getAbsolutePath();
  226.         }
  227.     }

  228.     /** *//**
  229.     * Prints the debug information.
  230.     *
  231.     * @param writerName the writer name
  232.     * @param encoding the encoding
  233.     */
  234.     private void printDebugInformation(String writerName, String encoding,
  235.             String content) {
  236.         StringBuffer msg = new StringBuffer();
  237.         msg.append("\n<<<<----------------------------------");
  238.         msg.append(" Test written by ").append(writerName);
  239.         msg.append(" with encoding ").append(encoding);
  240.         msg.append(" ---------------------------------->>>>\n");
  241.         msg.append(" \nOriginal string: ").append(content).append("\n");
  242.         System.out.println(msg.toString());
  243.     }

  244.     /** *//**
  245.     * Reset default system encoding.
  246.     */
  247.     private void resetDefaultSystemEncoding() {
  248.         System.setProperty("file.encoding", DEFAULT_SYSTEM_ENCODING);
  249.     }
  250. }
復制代碼
【1】中文平臺情況下,測試結(jié)果如下:
1.如果采用FileWriter,并指定GBK編碼:編碼后字符長度為15,可以正常保存和讀取
2.如果采用FileWriter,并指定UTF-8編碼:編碼后字節(jié)長度為16,可以正常保存和讀取
3.如果采用FileWriter,并指定ISO8859-1編碼:編碼后字節(jié)長度為17,可以正常保存和讀取

4.如果采用OutputStreamWriter,并指定GBK編碼:編碼后字符長度為15,可以正常保存和讀取
5.如果采用OutputStreamWriter,并指定UTF-8編碼:編碼后字節(jié)長度為16,可以正常保存和讀取
6.如果采用OutputStreamWriter,并指定ISO-8859-1編碼:編碼后字節(jié)長度為17,變成?

【2】英文平臺情況下,測試結(jié)果如下:
1.如果采用FileWriter,并指定GBK編碼:編碼后字符長度為15,變成?
2.如果采用FileWriter,并指定UTF-8編碼:編碼后字節(jié)長度為16,變成?
3.如果采用FileWriter,并指定ISO-8859-1編碼:編碼后字節(jié)長度為17,變成?

4.如果采用OutputStreamWriter,并指定GBK編碼:編碼后字符長度為15,可以正常保存和讀取
5.如果采用OutputStreamWriter,并指定UTF-8編碼:編碼后字節(jié)長度為16,可以正常保存和讀取
6.如果采用OutputStreamWriter,并指定ISO-8859-1編碼:編碼后字節(jié)長度為17,變成?

【結(jié)論】

①在中文平臺下,如果使用FileWriter,不論你如何設置字符集都不會起作用。因為它采用的是默認的系統(tǒng)字符集。即便你設置了 System.setProperty("file.encoding", "ISO-8859-1"),或者在運行時給予參數(shù)-Dfile.encoding=UTF-8都不會起作用。你會發(fā)現(xiàn)它最終還是都已"GB2312"或者"GBK"的方式保存。
 
在中文平臺下,如果使用OutputStreamWriter,則在后臺寫入時會把字符流轉(zhuǎn)換成字節(jié)流,此時指定的編碼字符集就起作用了??梢钥吹皆谥付?GBK、UTF-8的情況下中文可以正常的保存和讀取,同時文件按照我們給定的方式保存了。而對于ISO-8859-1則變成了?,這再次證明了采用 ISO-8859-1是不能保存中文的,而且會因為中文編碼在ISO-8859-1的編碼中找不到對應的字符而默認轉(zhuǎn)換成?。

②在英文平臺下,如果使用FileWriter,不論你如何設置字符集同樣都不會起作用。所有的文件都將按照ISO-8859-1的編碼方式保存,毫無疑問地變成了?。在英文平臺下,如果使用OutputStreamWriter,則只有當我們把字符和文件的編碼方式正確設置為GBK、UTF-8的情況下,中文才能正確的保存并顯示。

③通過上述的實驗證明,為了確保在不同的平臺下,客戶端輸入的中文可以被正確地解析、保存、讀取。最好的辦法就是使用 OutputStreamWriter配合UTF-8編碼。
 
如果不想使用UTF-8編碼,那么可以考慮使用GB2312,不建議使用GBK、GB18030。因為對于某些老式的文本編輯器,甚至不支持GBK、 GB18030的編碼,但是對于GB2312則是一定支持的。因為前兩者都不是國標但后者是。

④關于String的getBytes(),getBytes(encoding)和new String(bytes, encoding)這三個方法,非常值得注意:
 
  A.getBytes():使用平臺默認的編碼方式(通過file.encoding屬性獲取)方式來將字符串轉(zhuǎn)換成byte[]。得到的是字符串最原始的字節(jié)編碼值。
 
  B.getBytes(NAME_OF_CHARSET):使用指定的編碼方式將字符串轉(zhuǎn)換成byte[],如果想要得到正確的字節(jié)數(shù)組,程序員必須給出正確的NAME_OF_CHARSET。否則得到的就不會得到正確的結(jié)果。
 
  C.new String(bytes, encoding):如果我們在客戶端使用UTF-8編碼的JSP頁面發(fā)出請求,瀏覽器編碼后的UTF-8字節(jié)會以ISO-8859-1的形式傳遞到服務器端。所以要得到經(jīng)HTTP協(xié)議傳輸?shù)脑甲止?jié),我們需要先調(diào)用getBytes("ISO-8859-1")得到原始的字節(jié),但由于我們客戶端的原始編碼是UTF-8,如果繼續(xù)按照ISO-8859-1解碼,那么得到的將不是一個中文字符,而是3個亂碼的字符。所以我們需要再次調(diào)用new String(bytes,"UTF-8"),將字節(jié)數(shù)組按照UTF-8的格式,每3個一組進行解碼,才能還原為客戶端的原始字符。

  D.String的getBytes()、getBytes(NAME_OF_CHARSET)方法都是比較微妙的方法,原則上:傳輸時采用的是什么編碼,我們就需要按照這種編碼得到字節(jié)。new String(bytes, NAME_OF_CHARSET)則更加需要小心,原則上:客戶端采用的是什么編碼,那么這里的NAME_OF_CHARSET就必須和客戶端保持一致。
   
  例如JSP頁面是GBK,那么我們接收頁面?zhèn)鬟f而來的參數(shù)時就必須使用new String(parameter.getBytes("ISO-8859-1"), "GBK");如果使用了錯誤的解碼方式,如使用了UTF-8,那么得到的很有可能就是亂碼了。
   
  也就是說:GBK--->ISO-8859-1--->GBK、UTF-8--->ISO-8859-1--->UTF- 8的轉(zhuǎn)換過程是沒有問題的。但是GBK--->ISO-8859-1--->UTF-8、UTF-8--->ISO- 8859-1--->GBK的字節(jié)直接轉(zhuǎn)碼則可能導致亂碼,需要另外的轉(zhuǎn)換過程。

記?。?/strong>

謹慎地使用getBytes(NAME_OF_CHARSET)和new String(bytes, NAME_OF_CHARSET),除非你很清楚的知道原始的字符編碼和傳輸協(xié)議使用的編碼。

推薦使用基于服務器的配置、過濾器設置request/response的characterEncoding、content type屬性。還有就是JSP頁面的pageEncoding屬性、HTML meta元素的content type屬性。盡量避免頻繁的在代碼中進行字符串轉(zhuǎn)碼,即降低了效率又增加了風險。(文/Paul Lin

下一篇:【Java 基礎專題】編碼與亂碼(05)---GBK與UTF-8之間的轉(zhuǎn)換
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服