[英]Java ByteBuffer to String
這是以這種方式將 ByteBuffer 轉換為 String 的正確方法嗎,
String k = "abcd";
ByteBuffer b = ByteBuffer.wrap(k.getBytes());
String v = new String(b.array());
if(k.equals(v))
System.out.println("it worked");
else
System.out.println("did not work");
我問的原因是這看起來太簡單了,而其他方法如Java:將字符串轉換為 ByteBuffer 和相關問題看起來更復雜。
Andy Thomas 提到有一種更簡單的方法可以將ByteBuffer
解碼為String
而不會出現任何問題。
String s = StandardCharsets.UTF_8.decode(byteBuffer).toString();
編輯(2018): @xinyongCheng 編輯的兄弟答案是一種更簡單的方法,應該是公認的答案。
如果您知道字節在平台的默認字符集中,您的方法將是合理的。 在您的示例中,這是正確的,因為k.getBytes()
返回平台默認字符k.getBytes()
的字節。
更常見的是,您需要指定編碼。 但是,有一種比您鏈接的問題更簡單的方法。 String API 提供了以特定編碼在 String 和 byte[] 數組之間進行轉換的方法。 這些方法建議使用 CharsetEncoder/CharsetDecoder, “當需要對解碼 [編碼] 過程進行更多控制時”。
要從特定編碼的字符串中獲取字節,您可以使用同級 getBytes() 方法:
byte[] bytes = k.getBytes( StandardCharsets.UTF_8 );
要將具有特定編碼的字節放入 String,您可以使用不同的 String 構造函數:
String v = new String( bytes, StandardCharsets.UTF_8 );
請注意, ByteBuffer.array()
是一個可選操作。 如果您使用數組構建了 ByteBuffer,則可以直接使用該數組。 否則,如果您想安全,請使用ByteBuffer.get(byte[] dst, int offset, int length)
從緩沖區獲取字節到字節數組中。
試試這個:
new String(bytebuffer.array(), "ASCII");
注意。 在不知道其編碼的情況下,您無法正確地將字節數組轉換為字符串。
我希望這有幫助
只是想指出,假設 ByteBuffer.array() 總是有效是不安全的。
byte[] bytes;
if(buffer.hasArray()) {
bytes = buffer.array();
} else {
bytes = new byte[buffer.remaining()];
buffer.get(bytes);
}
String v = new String(bytes, charset);
通常 buffer.hasArray() 將始終為 true 或 false,具體取決於您的用例。 在實踐中,除非你真的希望它在任何情況下都能工作,否則優化掉你不需要的分支是安全的。 但是其余的答案可能不適用於通過 ByteBuffer.allocateDirect() 創建的 ByteBuffer。
簡單地調用array()
的答案並不完全正確:當緩沖區被部分消耗時,或者指的是數組的一部分(您可以ByteBuffer.wrap
給定偏移量的數組,不一定從頭開始) ,我們必須在計算中考慮到這一點。 這是適用於所有情況下的緩沖區的通用解決方案(不包括編碼):
if (myByteBuffer.hasArray()) {
return new String(myByteBuffer.array(),
myByteBuffer.arrayOffset() + myByteBuffer.position(),
myByteBuffer.remaining());
} else {
final byte[] b = new byte[myByteBuffer.remaining()];
myByteBuffer.duplicate().get(b);
return new String(b);
}
有關與編碼相關的問題,請參閱 Andy Thomas 的回答。
這個問題的根源是如何將字節解碼為字符串?
這可以通過 JAVA NIO CharSet 來完成:
public final CharBuffer decode(ByteBuffer bb)
FileChannel channel = FileChannel.open(
Paths.get("files/text-latin1.txt", StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
CharSet latin1 = StandardCharsets.ISO_8859_1;
CharBuffer latin1Buffer = latin1.decode(buffer);
String result = new String(latin1Buffer.array());
將 String 轉換為 ByteBuffer,然后使用 Java 將 ByteBuffer 轉換回 String:
import java.nio.charset.Charset;
import java.nio.*;
String babel = "obufscate thdé alphebat and yolo!!";
System.out.println(babel);
//Convert string to ByteBuffer:
ByteBuffer babb = Charset.forName("UTF-8").encode(babel);
try{
//Convert ByteBuffer to String
System.out.println(new String(babb.array(), "UTF-8"));
}
catch(Exception e){
e.printStackTrace();
}
它首先打印打印的裸字符串,然后將 ByteBuffer 轉換為 array():
obufscate thdé alphebat and yolo!!
obufscate thdé alphebat and yolo!!
這對我也很有幫助,將字符串減少到原始字節可以幫助檢查發生了什么:
String text = "こんにちは";
//convert utf8 text to a byte array
byte[] array = text.getBytes("UTF-8");
//convert the byte array back to a string as UTF-8
String s = new String(array, Charset.forName("UTF-8"));
System.out.println(s);
//forcing strings encoded as UTF-8 as an incorrect encoding like
//say ISO-8859-1 causes strange and undefined behavior
String sISO = new String(array, Charset.forName("ISO-8859-1"));
System.out.println(sISO);
打印解釋為 UTF-8 的字符串,然后再次打印為 ISO-8859-1:
こんにちは
ããã«ã¡ã¯
請注意(除了編碼問題),一些更復雜的鏈接代碼在獲取有問題的 ByteBuffer 的“活動”部分時遇到了麻煩(例如通過使用位置和限制),而不是簡單地對所有字節進行編碼在整個支持數組中(就像這些答案中的許多示例一樣)。
private String convertFrom(String lines, String from, String to) {
ByteBuffer bb = ByteBuffer.wrap(lines.getBytes());
CharBuffer cb = Charset.forName(to).decode(bb);
return new String(Charset.forName(from).encode(cb).array());
};
public Doit(){
String concatenatedLines = convertFrom(concatenatedLines, "CP1252", "UTF-8");
};
這是一個將字節緩沖區轉換為字符串的簡單函數:
public String byteBufferToString(ByteBuffer bufferData) {
byte[] buffer = new byte[bufferData.readableByteCount()];
// read bufferData and insert into buffer
data.read(buffer);
// CharsetUtil supports UTF_16, ASCII, and many more
String text = new String(buffer, CharsetUtil.UTF_8);
System.out.println("Text: "+text);
return text;
}
這是在java.nio.ByteBuffer
實例上對我java.nio.ByteBuffer
的唯一方法:
String fileContent = new String(bb.array(), StandardCharsets.UTF_8);
相關代碼片段如下:
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
Path path = Paths.get("/home/binita/testbb");
FileChannel fileChannel = FileChannel.open(path,
EnumSet.of(StandardOpenOption.READ
)
);
ByteBuffer bb = ByteBuffer.allocate(1024);
int bytesRead = fileChannel.read(bb);
if(bytesRead > 0) {
String fileContent = new String(bb.array(), StandardCharsets.UTF_8);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.