JAVA基礎知識之InputStreamReader流 和 將本地文件通過前端上傳到服務器上


將本地文件通過前端上傳到服務器上 
public BaseResponseSwagger resolveFile(@Valid @ApiParam(value = "file")@RequestParam(name = "file",required = true) MultipartFile file){
if(file.isEmpty()){
throw new SoftwareException(ComStatusCodeEnum.COM_PARAM_VALID_ERROR,"文件為空");
}
String path=SoftwareConfig.ZIP_PATH;
File dir = new File(path);
if(!dir.exists()){
dir.mkdirs();
}
UUID id = UUID.randomUUID();
String fileName = file.getOriginalFilename();
String zipName = id+fileName.substring(fileName.lastIndexOf("."));
try {
FileOutputStream zipOut = new FileOutputStream(new File(dir,zipName));
zipOut.write(file.getBytes());
zipOut.close();

}catch (Exception e){
throw new SoftwareException(ComStatusCodeEnum.COM_ERROR,"zip包存到服務器失敗");
}
Map<String,String> map = new HashMap<>();
map.put("path",zipName);
return new BaseResponseSwagger(JSON.toJSONString(map));
}

一、InputStreamReader類
    API文檔說明:InputStreamReader類是從字節流到字符流的橋接器:它使用指定的字符集讀取字節並將它們解碼為字符。 它使用的字符集可以通過名稱指定,也可以明確指定,或者可以接受平台的默認字符集。每次調用一個InputStreamReader的read()方法都可能導致從底層字節輸入流中讀取一個或多個字節。 為了實現字節到字符的有效轉換,可以從基礎流中提取比滿足當前讀取操作所需的更多字節。為了獲得最高效率,請考慮在BufferedReader中包裝InputStreamReader

   其繼承Reader類

public class InputStreamReader extends Reader {}
1)字節流到字符流的橋梁怎么理解?

    1、計算機存儲的單位是字節,如盡管txt文本中有中文漢字這樣的字符,但是對計算機而言,其是字節形式存在的

    2、字節流讀取是單字節讀取,但是不同字符集解碼成字符需要不通過個數,因此字節流讀取會報錯

   3、 那么就需要一個流把字節流讀取的字節進行緩沖而后在通過字符集解碼成字符返回,因而形式上看是字符流

    4、InputStreamReader流就是起這個作用,實現從字節流到字符流的轉換

2)使用指定的字符集讀取字節並將它們解碼為字符怎么理解?

      字節本質是8個二進制位,且不同的字符集對同一字節解碼后的字符結果是不同的,因此在讀取字符時務必要指定合適的字符集,否則讀取的內容會產生亂碼

3)它使用的字符集可以通過名稱指定,也可以明確指定,或者可以接受平台的默認字符集怎么理解?

      意味着InputStreamReader類有多個方法或者多個構造方法來設置字符集

4)每次調用一個InputStreamReader的read()方法都可能導致從底層字節輸入流中讀取一個或多個字節怎么理解?

      read()方法會嘗試盡量沖底層字節流中讀取2個字符到字符緩沖區中,注意這里是盡量,若遇到文件最后字符,則就只能讀取到1個字符,因此每次read()方法讀取的字節數是不定的

5)為了實現字節到字符的有效轉換,可以從基礎流中提取比滿足當前讀取操作所需的更多字節,請考慮在BufferedReader中包裝InputStreamReader

     該話暫未理解,需要了解BufferedReader類后對比讀取效率才可得出答案

 

二、InputStreamReader構造方法
1)使用默認的字符集構造InputStreamReader流:本質是初始化其實例域的一個變量,並未看到任何關於字符集的設置

public InputStreamReader(InputStream in) {
super(in);
try {
sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
} catch (UnsupportedEncodingException e) {

throw new Error(e);
}
}
2)使用指定的字符集名稱構造InputStreamReader流:本質是初始化其實例域的一個變量,可以發現字符集是初始化方法的第三個參數

public InputStreamReader(InputStream in, String charsetName)
throws UnsupportedEncodingException
{
super(in);
if (charsetName == null)
throw new NullPointerException("charsetName");
sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
}
3)sd變量:本質是StreamDecoder類的對象,InputStreamReader的構造方法就是在給此對象做初始化操作

private final StreamDecoder sd;
  三、InputStreamReaderAPI
 1、我們可以發現InputStreamReaderAPI類的所有API都是利用了sd變量的,因此可以看出InputStreamReader類的方法本質是調用StreamDecoder類方法

2、因此我們需要了解StreamDecoder類,以便了解到InputStreamReader類的方法是如何起實質性作用的


/**
* 獲取設置的字符集
*/
public String getEncoding() {
return sd.getEncoding();
}

/**
* 讀取流並返回一個字符,遇到文件末尾返回-1
*/
public int read() throws IOException {
return sd.read();
}

/**
* 讀取字符到字符數組的部分中,遇到文件末尾返回-1
*/
public int read(char cbuf[], int offset, int length) throws IOException {
return sd.read(cbuf, offset, length);
}

/**
* 檢測流是否准備好唄讀取
*/
public boolean ready() throws IOException {
return sd.ready();
}

/**
* 關閉流並釋放資源
*/
public void close() throws IOException {
sd.close();
}
 

五、InputStreamReader類與FileReader類關系
      1、FileReader類僅僅是InputStreamReader的簡單衍生並未擴展任何功能

      2、FileReader類讀取數據實質是InputStreamReader類在讀取,而InputStreamReader讀取數據實際是StreamDecoder類讀取

      3、因此在使用字符輸入流的時候實際是StreamDecoder類在發揮作用

參考原文鏈接:https://blog.csdn.net/ai_bao_zi/article/details/81133476


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM