8

Tôi đang thử nghiệm tính tương thích i18n của ứng dụng của mình. Tôi có phiên bản tiếng Anh của Windows 7 có nghĩa là ngôn ngữ hiển thị của hệ thống là tiếng Anh. Và tôi đặt ngôn ngữ hệ thống là tiếng Trung cho ứng dụng không phải unicode.Charset.defaultCharset() nhận kết quả khác dưới JDK1.7 và JDK 1.6

Ứng dụng của tôi gặp sự cố khi xuất tệp Html có ký tự Trung Quốc dưới jdk1.6, nhưng hoạt động tốt khi chạy dưới jdk1.7.

Tôi đã sửa lỗi và tìm ra lý do trực tiếp là Charset.defaultCharset() trả về các giá trị khác nhau.

Dưới jdk1.7 Charset.defaultCharset() trả lại GBK là bộ ký tự cho tiếng Trung.

Dưới jdk1.6 Charset.defaultCharset() trả lại window_1252 là bộ ký tự cho ngôn ngữ Latinh.

Tôi biết vấn đề có thể được giải quyết bằng cách chỉ định bảng mã, nói utf-8, bằng mã.

Nhưng tôi muốn biết lý do tại sao Charset.defaultCharset() trả về các giá trị khác nhau theo JDK1.7 và JDK 1.6.

+1

Khi đoán, hãy đọc cài đặt "ngôn ngữ cho ứng dụng không phải Unicode" là tính năng mới trong JRE 7. của Windows (tôi đoán vì nó có thể không đủ quan trọng để đề cập trong ghi chú phát hành và tính năng tìm kiếm cho cơ sở dữ liệu lỗi không thực sự tìm kiếm cơ sở dữ liệu lỗi.) – millimoose

+3

Đã có một số [Cải tiến Unicode và Quốc tế] (http://download.oracle.com/javase/7/docs/technotes/guides/intl /enhancements.7.html) trong Java 7 - có lẽ điều này đã đi kèm với nó. – Bringer128

+1

Bạn có thể đăng những gì bạn nhận được bằng cách gọi 'System.getProperty (" file.encoding ")' trong cả jdk 6 và 7? – mindas

Trả lời

3

Charset.defaultCharset() cung cấp bộ ký tự JVM đang chạy, vì vậy nó không phải lúc nào cũng có cùng giá trị. Ví dụ, nếu bạn đang chạy các chương trình của bạn với Netbeans, nó sẽ luôn trả về UTF-8, vì đó là mã hóa mặc định cho các Dự án Java trong Netbeans.

Tôi có thiết lập tương tự như của bạn. Windows của tôi là tiếng Anh (menu, hộp thoại là tiếng Anh) và tôi đang sử dụng tiếng Thổ Nhĩ Kỳ cho các ứng dụng không phải Unicode. Khi tôi bắt đầu JVM mà không có bất kỳ cờ hoặc tham số hệ thống nào, cả hai lần chạy Java 7 và Java 6 đều cho "CP1254" khi gọi Charset.defaultCharset(). System.getProperty("file.encoding") và mã hóa IO mặc định cũng giống nhau. (Ngôn ngữ của hệ thống là khác nhau trong hai phiên bản Java này, tuy nhiên đó là một câu chuyện khác.)

Vì vậy, tôi đoán vấn đề của bạn là cách bạn khởi động JVM hoặc về cách JVM quyết định mã hóa mặc định. Nếu bạn chắc chắn rằng vấn đề không phải là vấn đề cũ (bạn chạy JVM mà không có tham số mã hóa nào và bạn không cố gắng thay đổi bộ ký tự mặc định ở bất kỳ đâu trong chương trình của bạn), thì JVM sẽ lấy mã hóa mặc định không chính xác và có lẽ đó là hành vi bất thường.

3

Các Java 7 technote nói:

Các kiểu mã hóa được hỗ trợ khác nhau giữa hiện thực khác nhau của Java Platform , Standard Edition 7 (Java SE 7).

Các Charset doc nói:

Mỗi thể hiện của các máy ảo Java có charset mặc định, mà có thể hoặc không thể là một trong những bảng mã chuẩn. Bộ mã hoá mặc định được xác định trong khi khởi động máy ảo và thường là phụ thuộc vào ngôn ngữ và bộ mã được sử dụng bởi hệ điều hành cơ bản.

Ngoài ra, tôi đã tìm thấy một "bug" về việc sử dụng -Dfile.encoding với đánh giá cuối cùng này:

Đây không phải là một lỗi. Thuộc tính "file.encoding" không được yêu cầu bởi đặc tả nền tảng J2SE; nó là một chi tiết bên trong của việc triển khai của Sun và không được kiểm tra hoặc sửa đổi bởi mã người dùng. Nó cũng có ý định chỉ đọc; về mặt kỹ thuật, không thể hỗ trợ cài đặt thuộc tính này thành các giá trị tùy ý trên dòng lệnh hoặc bất kỳ lúc nào khác trong khi thực thi chương trình.

Cách ưa thích để thay đổi mã hóa mặc định được VM sử dụng và hệ thống thời gian chạy là thay đổi ngôn ngữ của nền tảng cơ bản trước khi bắt đầu chương trình Java của bạn.