簡體   English   中英

將InputStream的Latin-1內容轉換為UTF-8字符串

[英]Convert Latin-1 content of InputStream into UTF-8 String

我需要將InputStream的內容轉換為String。 這里的難點是輸入編碼,即Latin-1。 我嘗試了幾種方法和代碼片段,包括String,getBytes,char []等,以便直接獲得編碼,但似乎沒有任何效果。

最后,我想出了下面的工作解決方案。 但是,這個代碼對我來說似乎有點冗長,即使對於Java也是如此。 所以這里的問題是:

有沒有更簡單,更優雅的方法來實現這里所做的事情?

private String convertStreamToStringLatin1(java.io.InputStream is)
        throws IOException {

    String text = "";

    // setup readers with Latin-1 (ISO 8859-1) encoding
    BufferedReader i = new BufferedReader(new InputStreamReader(is, "8859_1"));

    int numBytes;
    CharBuffer buf = CharBuffer.allocate(512);
    while ((numBytes = i.read(buf)) != -1) {
        text += String.copyValueOf(buf.array(), 0, numBytes);
        buf.clear();
    }

    return text;
}

首先,對你已采取的方法提出一些批評。 當你只想要一個char[512]時,你不應該不必要地使用NIO CharBuffer 您也不需要每次迭代都clear緩沖區。

int numBytes;
final char[] buf = new char[512];
while ((numBytes = i.read(buf)) != -1) {
    text += String.copyValueOf(buf, 0, numBytes);
}

您還應該知道,只使用這些參數構造String將具有相同的效果,因為構造函數也會復制數據。

子陣列的內容被復制; 后續修改字符數組不會影響新創建的字符串。


您可以使用動態ByteArrayOutputStream來增加內部緩沖區以容納所有數據。 然后,您可以使用toByteArray的整個byte[]解碼為String

優點是推遲解碼直到最后避免單獨解碼片段; 雖然這可能適用於簡單的字符集,如ASCII或ISO-8859-1,但它不適用於UTF-8和UTF-16等多字節方案。 這意味着將來更容易更改字符編碼,因為代碼不需要修改。

private static final String DEFAULT_ENCODING = "ISO-8859-1";

public static final String convert(final InputStream in) throws IOException {
  return convert(in, DEFAULT_ENCODING);
}

public static final String convert(final InputStream in, final String encoding) throws IOException {
  final ByteArrayOutputStream out = new ByteArrayOutputStream();
  final byte[] buf = new byte[2048];
  int rd;
  while ((rd = in.read(buf, 0, 2048) >= 0) {
    out.write(buf, 0, rd);
  }
  return new String(out.toByteArray(), 0, encoding);
}

我不明白它怎么可能簡單得多。 我曾經這樣做過一次......如果你已經有了一個String,你可以這樣做:

new String(originalString.getBytes(), "ISO-8859-1");

所以這樣的事情也可以起作用:

BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
  sb.append(line + "\n");
}
is.close();
return new String(sb.toString().getBytes(), "ISO-8859-1");

編輯:我應該補充一點,這實際上只是您已經工作的解決方案的替代品。 當談到在Java中轉換Streams時,它不會簡單得多,所以去吧。 :)

如果你不想自己探測它,你可以看看apo commons io項目, IOUtils.toString(InputStream輸入,字符串編碼) ,這似乎可以做你想要的。 我自己沒有嘗試過該方法,但是java doc聲明“ 使用指定的字符編碼將InputStream的內容作為String獲取。”

Guava的IO包非常好用。

Files.toString(yourFile, CharSets.ISO_8859_1)

或者來自溪流

new String(ByteStreams.toByteArray(stream), CharSets.ISO_8859_1)

我剛剛發現這個問題的答案 讀取/將InputStream轉換為String可以應用於我的問題,請參閱下面的代碼。 無論如何,我非常感謝你到目前為止給出的答案。

private String convertStreamToString(InputStream is, String charsetName) {
    try {
        return new java.util.Scanner(is, charsetName).useDelimiter("\\A").next();
    } catch (java.util.NoSuchElementException e) {
        return "";
    }
}

所以為了從Latin-1編碼,請像這樣調用:

String message = convertStreamToString(is, "8859_1");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM