จะรับสตริงตัวอักษร“ UTF-8” ใน Java ได้จากที่ใด?


490

ฉันพยายามที่จะใช้ค่าคงที่แทนตัวอักษรสตริงในรหัสชิ้นนี้:

new InputStreamReader(new FileInputStream(file), "UTF-8")

"UTF-8"ปรากฏในรหัสค่อนข้างบ่อยและจะดีกว่ามากในการอ้างอิงstatic finalตัวแปรบางตัวแทน คุณรู้หรือไม่ว่าฉันสามารถค้นหาตัวแปรใน JDK ได้ที่ไหน?

ในความคิดที่สอง BTW ค่าคงที่ดังกล่าวเป็นการออกแบบที่ไม่ดี: ตัวอักษรคงที่สาธารณะ ... ไม่ใช่วิธีแก้ปัญหาสำหรับการทำสำเนาข้อมูล



1
หมายเหตุ: หากคุณใช้ Java 7 อยู่ให้ใช้Files.newBufferedWriter(Path path, Charset cs)จาก NIO
Franklin Yu

คำตอบ:


836

ใน Java 1.7+, java.nio.charset.StandardCharsetsกำหนดค่าคงที่สำหรับรวมทั้งCharsetUTF_8

import java.nio.charset.StandardCharsets;

...

StandardCharsets.UTF_8.name();

สำหรับ Android: minSdk 19


3
คุณใช้. toString () กับสิ่งนั้นหรือไม่
Matt Broekhuis

54
.toString()จะทำงาน .name()แต่ฟังก์ชั่นที่เหมาะสมคือ 99.9% toString ไม่ใช่คำตอบ
Roger

1
btw .displayName()จะทำงานหากไม่ได้ถูกแทนที่สำหรับการแปลตามที่ตั้งใจไว้
Roger

36
คุณไม่จำเป็นต้องโทรname()เลย คุณสามารถส่งผ่านCharsetวัตถุโดยตรงไปยังตัวInputStreamReaderสร้าง
Natix

6
และยังมี libs อื่น ๆ อีกซึ่งจำเป็นต้องมีStringอาจเป็นเพราะเหตุผลดั้งเดิม ในกรณีเช่นนี้ฉันเก็บCharsetวัตถุไว้รอบ ๆ ซึ่งโดยทั่วไปจะได้มาจากStandardCharsetsและใช้name()ถ้าจำเป็น
Magnilex

134

ตอนนี้ผมใช้org.apache.commons.lang3.CharEncoding.UTF_8คงที่จากคอมมอน-lang


4
สำหรับผู้ที่ใช้ Lang org.apache.commons.lang3.CharEncoding.UTF_83.0: (หมายเหตุ "lang3")
รัสเซลซิลวา

24
หากคุณใช้ Java 1.7 ดูคำตอบ @ Roger ด้านล่างเนื่องจากเป็นส่วนหนึ่งของไลบรารีมาตรฐาน
Drew Stephens

2
PS "@ คำตอบของโรเจอร์ด้านล่าง" คือตอนนี้ @ คำตอบของโรเจอร์ข้างต้น
Gary S.

คลาสนั้นเลิกใช้แล้วเนื่องจาก Java 7 แนะนำ java.nio.charset.StandardCharsets
sendon1982

66

Google ฝรั่งห้องสมุด (ซึ่งผมขออยากแนะนำให้อยู่แล้วถ้าคุณกำลังทำผลงานใน Java) มีCharsetsระดับกับเขตข้อมูลคงเหมือนCharsets.UTF_8, Charsets.UTF_16ฯลฯ

ตั้งแต่ Java 7 คุณควรใช้java.nio.charset.StandardCharsetsแทนค่าคงที่ที่เทียบเท่ากัน

โปรดทราบว่าค่าคงที่เหล่านี้ไม่ใช่สตริง แต่เป็นCharsetอินสแตนซ์จริง API มาตรฐานทั้งหมดที่ใช้ชื่อชุดอักขระมีโอเวอร์โหลดที่ใช้Charsetวัตถุที่คุณควรใช้แทน


3
ดังนั้นควรเป็น Charsets.UTF_8.name ()
AlikElzin-kilaka

1
@kilaka Yeah ใช้ชื่อ () แทน getDisplayName () เนื่องจากชื่อ () ถือเป็นที่สิ้นสุดและ getDisplayName () ไม่ใช่
RKumsher

3
@Buffalo: โปรดอ่านคำตอบของฉันอีกครั้ง: แนะนำให้ใช้java.nio.charset.StandardCharsetsเมื่อเป็นไปได้ซึ่งไม่ใช่รหัสบุคคลที่สาม นอกจากนี้คำจำกัดความของ Guava Charsets ไม่ใช่ "แก้ไขอย่างต่อเนื่อง" และ AFAIK ไม่เคยทำลายความเข้ากันได้ย้อนหลังดังนั้นฉันไม่คิดว่าคำวิจารณ์ของคุณจะได้รับการรับประกัน
Daniel Pryden

2
@Buffalo: นั่นอาจเป็นไปได้ แต่ฉันสงสัยว่าปัญหาของคุณเกี่ยวกับการCharsetsเรียน หากคุณต้องการบ่นเกี่ยวกับ Guava ก็ดี แต่นี่ไม่ใช่สถานที่สำหรับการร้องเรียนเหล่านั้น
Daniel Pryden

1
โปรดอย่ารวมไลบรารีหลายเมกะไบต์เพื่อรับค่าคงที่หนึ่งสตริง
Jeffrey Blattman

50

ในกรณีที่หน้านี้เกิดขึ้นในการค้นหาเว็บ someones ในฐานะของ Java 1.7 ตอนนี้คุณสามารถใช้java.nio.charset.StandardCharsetsเพื่อรับการเข้าถึงคำจำกัดความคงที่ของ charsets มาตรฐาน


ฉันพยายามใช้สิ่งนี้ แต่ดูเหมือนจะไม่ทำงาน 'Charset.defaultCharset ()); ดูเหมือนว่าจะทำงานหลังจากรวม 'java.nio.charset. *' แต่ฉันไม่สามารถอ้างถึง UTF8 อย่างชัดเจนเมื่อฉันพยายามใช้ 'File.readAllLines'
Roger

1
@ Roger สิ่งที่ดูเหมือนจะเป็นปัญหาหรือไม่ จากสิ่งที่ฉันเห็นคุณสามารถโทร:Files.readAllLines(Paths.get("path-to-some-file"), StandardCharsets.UTF_8);
cosjav

ฉันไม่รู้ว่าปัญหาคืออะไร แต่มันใช้ได้ผลกับฉันหลังจากเปลี่ยนสิ่งที่ฉันจำไม่ได้
Roger

1
^^^ คุณอาจต้องเปลี่ยนแพลตฟอร์มเป้าหมายใน IDE หาก 1.6 เป็น JDK ล่าสุดของคุณเมื่อคุณติดตั้ง IDE มันอาจเลือกเป็นค่าเริ่มต้นและเก็บไว้เป็นค่าเริ่มต้นหลังจากคุณอัปเดตทั้ง IDE และ JDK ด้วยตนเอง
Bitbang3r

10

อย่างต่อเนื่องนี้จะใช้ได้ (ผู้อื่นเช่นUTF-16, US-ASCIIฯลฯ ) ในชั้นเรียนorg.apache.commons.codec.CharEncodingได้เป็นอย่างดี


9

ไม่มี (อย่างน้อยในไลบรารี Java มาตรฐาน) ชุดอักขระแตกต่างกันไปในแต่ละแพลตฟอร์มดังนั้นจึงไม่มีรายการมาตรฐานใน Java

มีห้องสมุดบุคคลที่สามที่มีค่าคงที่เหล่านี้อยู่ หนึ่งในนั้นคือ Guava (ห้องสมุดหลักของ Google): http ://guava-l ไลบรารี. googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets.html


ฉันใช้เวลาไม่กี่วินาทีในการจับสิ่งนี้ ... ค่าคงที่ของ Charsets ของ Guava คือ Charsets (ไม่แปลกใจ) ไม่ใช่ Strings InputStreamReader มีตัวสร้างอื่นที่ใช้ Charset แทนที่จะเป็นสตริง หากคุณต้องการสตริงจริงๆเช่น Charsets.UTF_8.name ()
Ed Staub

1
ชุดอักขระอาจแตกต่างกันไปตามแต่ละแพลตฟอร์ม แต่รับประกันว่าจะมี UTF-8 อยู่
tar

3
ชุดอักขระทั้งหมดที่กำหนดไว้StandardCharsetsจะรับประกันว่าจะมีอยู่ในทุกการใช้งาน Java บนทุกแพลตฟอร์ม
Krzysztof Krasoń

8

คุณสามารถใช้Charset.defaultCharset()API หรือfile.encodingคุณสมบัติ

แต่ถ้าคุณต้องการค่าคงที่ของคุณเองคุณจะต้องกำหนดมันเอง


11
ชุดอักขระเริ่มต้นมักจะถูกกำหนดโดยระบบปฏิบัติการและการตั้งค่าตำแหน่งที่ตั้งฉันไม่คิดว่าจะมีการรับประกันว่าจะยังคงเหมือนเดิมสำหรับการเรียกใช้ Java หลายรายการ ดังนั้นนี่จึงไม่ใช่การแทนที่ค่าคงที่ "utf-8"
Jörn Horstmann

6

ใน Java 1.7+

อย่าใช้สตริง "UTF-8" แต่ให้ใช้Charsetพารามิเตอร์ชนิด:

import java.nio.charset.StandardCharsets

...

new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);

4

หากคุณใช้OkHttpสำหรับ Java / Android คุณสามารถใช้ค่าคงที่ต่อไปนี้:

import com.squareup.okhttp.internal.Util;

Util.UTF_8; // Charset
Util.UTF_8.name(); // String

2
มันถูกลบออกจาก OkHttp ดังนั้นวิธีต่อไปคือ: Charset.forName("UTF-8").name()เมื่อคุณต้องการการสนับสนุนสำหรับ Android ที่ต่ำกว่า API 19+ มิฉะนั้นคุณสามารถใช้:StandardCharsets.UTF_8.name()
mtrakal

3

คำจำกัดความคงที่สำหรับมาตรฐาน ชุดอักขระเหล่านี้รับประกันว่าจะมีอยู่ในทุกการใช้งานของแพลตฟอร์ม Java ตั้งแต่ 1.7

 package java.nio.charset;
 Charset utf8 = StandardCharsets.UTF_8;

0

คลาสorg.apache.commons.lang3.CharEncoding.UTF_8เลิกใช้แล้วหลังจากมีการนำ Java 7 มาใช้java.nio.charset.StandardCharsets

  • @see ชื่อการเข้ารหัสอักขระ JRE
  • @since 2.1
  • @deprecated Java 7 แนะนำ {@link java.nio.charset.StandardCharsets} ซึ่งกำหนดค่าคงที่เหล่านี้เป็น
  • วัตถุ {@link Charset} ใช้ {@link Charset # name ()} เพื่อรับค่าสตริงที่ให้ไว้ในคลาสนี้
  • คลาสนี้จะถูกลบออกในอนาคต
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.