教你一個小技巧:Inputstream 轉換 String
在本教程中,我們將講講如何將一個 InputStream 轉換為一個字串。
我們將從使用普通的 Java 開始,包括 Java 8+ 的解決方案,然後也會研究使用 Guava 和 Apache Commons IO 庫。
讓我們看看一個簡單的、低階別的方法,使用普通的 Java,一個 InputStream 和一個簡單的 StringBuilder。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); StringBuilder textBuilder = new StringBuilder(); try (Reader reader = new BufferedReader(new InputStreamReader (inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) { int c = 0; while ((c = reader.read()) != -1) { textBuilder.append((char) c); } } assertEquals(textBuilder.toString(), originalString); }
Java 8 給 BufferedReader 帶來了一個新的 lines() 方法。讓我們看看如何利用它將一個 InputStream 轉換為一個字串。
@Test public void convertingAnInputStreamToAString() { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = new BufferedReader( new InputStreamReader(inputStream, StandardCharsets.UTF_8)) .lines() .collect(Collectors.joining("\n")); assertThat(text, equalTo(originalString)); }
值得一提的是,lines() 使用的是 readLine() 方法。readLine() 假定一行是由換行("\n")、回車("\r")或回車後立即換行中的任何一種結束符。換句話說,它支援所有常見的行結束方式。
另一方面,當我們使用 Collectors.join() 時,我們需要明確決定我們要為建立的 String 使用哪種型別的結束符。
我們也可以使用 Collectors.join(System.lineSeparator()) ,在這種情況下,輸出結果取決於系統設定。
用 Java 9+ 進行轉換 - InputStream.readAllBytes()
如果我們在 Java 9 或以上版本,我們可以利用一個新的 readAllBytes 方法新增到 InputStream 中。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); assertThat(text, equalTo(originalString)); }
我們需要注意的是,這段簡單的程式碼是為那些方便將所有位元組讀入位元組陣列的簡單情況準備的。我們不應該用它來讀取有大量資料的輸入流。
接下來,讓我們看看一個使用標準文字掃描器的普通Java例子。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = null; try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) { text = scanner.useDelimiter("\\A").next(); } assertThat(text, equalTo(originalString)); }
請注意,InputStream 將被關閉的 Scanner 關閉。
同樣值得澄清的是 useDelimiter("\A") 的作用。這裡我們傳遞了'\A',它是一個邊界標記重碼,表示輸入的開始。本質上,這意味著 next() 呼叫讀取了整個輸入流。
使用 ByteArrayOutputStream 進行轉換
最後,讓我們看看另一個普通的Java例子,這次是使用 ByteArrayOutputStream 類。
@Test public void convertingAnInputStreamToString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[1024]; while ((nRead = inputStream.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); byte[] byteArray = buffer.toByteArray(); String text = new String(byteArray, StandardCharsets.UTF_8); assertThat(text, equalTo(originalString)); }
在這個例子中,InputStream 通過讀寫位元組塊被轉換為 ByteArrayOutputStream。然後 OutputStream 被轉換為一個位元組陣列,用來建立一個字串。
另一個解決方案是將 InputStream 的內容複製到一個檔案中,然後將其轉換為一個字串。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); Path tempFile = Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp"); Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); String result = new String(Files.readAllBytes(tempFile)); assertThat(result, equalTo(originalString)); }
這裡我們使用 java.nio.file.Files 類來建立一個臨時檔案,同時將 InputStream 的內容複製到檔案中。然後用同一個類用 readAllBytes() 方法將檔案內容轉換為一個字串。
讓我們從一個利用 ByteSource 功能的 Guava 例子開始。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); ByteSource byteSource = new ByteSource() { @Override public InputStream openStream() throws IOException { return inputStream; } }; String text = byteSource.asCharSource(Charsets.UTF_8).read(); assertThat(text, equalTo(originalString)); }
讓我們來看看這些步驟:
首先,我們把我們的 InputStream 包裝成一個 ByteSource.
其次,我們把 ByteSource 看作是一個具有 UTF8 字符集的 CharSource。
最後,我們使用 CharSource 將其作為一個字串來讀取。
一個更簡單的轉換方法是使用 Guava,但需要明確地關閉流, 我們可以簡單地使用 try-with-resources 語法來處理這個問題。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = null; try (Reader reader = new InputStreamReader(inputStream)) { text = CharStreams.toString(reader); } assertThat(text, equalTo(originalString)); }
現在讓我們來看看如何用 Commons IO 庫來做這個。
一個重要的注意事項是,與 Guava 不同的是,這些例子都不會關閉 InputStream。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name()); assertThat(text, equalTo(originalString)); }
我們也可以用一個StringWriter來做轉換。
ream 轉換為一個字串。我們從使用普通 Java 開始,然後探索瞭如何使用 Guava 和 Apache Commons IO 庫。
@Test public void convertingAnInputStreamToAString() throws IOException { String originalString = randomString(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); StringWriter writer = new StringWriter(); String encoding = StandardCharsets.UTF_8.name(); IOUtils.copy(inputStream, writer, encoding); assertThat(writer.toString(), equalTo(originalString)); }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2887665/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- InputStream流轉換成String字串字串
- android中String與InputStream之間的相互轉換方式Android
- 輸入流和字串互轉InputStream2String和String2InputStream字串
- Java 中將 InputStream 轉換為 StreamJava
- 小技巧:如何使用預覽將多個影像轉換為單個PDF
- CAD轉PNG格式,教你一招立刻轉換
- ppt轉pdf怎麼轉?試試這個轉換技巧!
- 轉換String三種方式比較:toString()、String.valueOf()、(String)
- Mybatis使用小技巧-自定義型別轉換器MyBatis型別
- postman 的一個小技巧!Postman
- string與數字相互轉換
- 型別轉換(int 和 String)型別
- Java String和Date的轉換Java
- 每天一個實用小技巧!教你在Mac上共享WiFi密碼MacWiFi密碼
- 一招教你heic格式批量轉換png,必會的格式轉換!
- 每天一個實用小技巧!教你在Mac上快速輸入長文字Mac
- string與char陣列相互轉換陣列
- Json,String,Map之間的轉換JSON
- python中的時間轉換,秒級時間戳轉string,string轉時間Python時間戳
- 每天一個小技巧(四)
- Android 多國語言轉換 Excel 和 Excel 轉換為 stringAndroidExcel
- c++中幾種常見的型別轉換。int與string的轉換,float與string的轉換以及string和long型別之間的相互轉換。to_string函式的實現和應用。C++型別函式
- Java-InputStream轉Base64Java
- 實用辦公小技巧:Word、Excel、PPT任意轉換教程Excel
- 教你一招,免費pdf轉換圖片
- 在 Linux 中把一個網頁轉換成 PDF的技巧介紹Linux網頁
- String to Integer (atoi) 字串轉換整數 (atoi)字串
- String和Date、Timestamp之間的轉換
- u8 陣列轉換成 string陣列
- TypeScript Partial 使用的一個小技巧TypeScript
- 6個小技巧教你編寫乾淨整潔的程式碼
- String.valueOf和強制型別轉換(String)的區別型別
- 記錄一個行列轉換
- PDF檔案如何轉換EXCEL,一個方法教你輕鬆轉換各種檔案,讓老闆驚喜不斷Excel
- simplexml_load_string 將xml轉換成物件XML物件
- scala常用操作-Tuple元祖轉換成String字串字串
- delphi:string,PChar,Array of Char 之間的轉換
- Map<String, Object>轉換成uri請求串Object