最近在做一個文件改造功能,把項目下面的pdf文件放到數據庫去,用流比較多,所以寫個博客記錄下
首先說MultipartResolver
MultipartResolver 用於處理文件上傳,當收到請求時 DispatcherServlet 的 checkMultipart() 方法會調用 MultipartResolver 的 isMultipart() 方法判斷請求中是否包含文件。如果請求數據中包含文件,則調用 MultipartResolver 的 resolveMultipart() 方法對請求的數據進行解析,然後將文件數據解析成 MultipartFile 並封裝在 MultipartHttpServletRequest (繼承了 HttpServletRequest) 對象中,最後傳遞給 Controller
MultipartFile 接口中有如下方法:
- String getName(); // 獲取參數的名稱
- String getOriginalFilename(); // 獲取文件的原名稱
- String getContentType(); // 文件內容的類型
- boolean isEmpty(); // 文件是否爲空
- long getSize(); // 文件大小
- byte[] getBytes(); // 將文件內容以字節數組的形式返回
- InputStream getInputStream(); // 將文件內容以輸入流的形式返回
- void transferTo(File dest); // 將文件內容傳輸到指定文件中
from表單
<form action="" method="post" enctype="multipart/form-data">
請選擇要上傳的文件:<input type="file" style="width: 120px;" id="file" name="file" class="text">
<input type="submit" value="上傳" />
</form>
controller處理
@RequestMapping("")
public ModelAndView insertpdf(@RequestParam(value = "file", required = false) MultipartFile file,HttpServletResponse response, HttpServletRequest request){
if(!file.isEmpty()) {
ContractPdf contractPdf = new ContractPdf();
try {
// 文件名稱
String name = String.valueOf(file.getOriginalFilename());
contractPdf.setType("1");
contractPdf.setContractCode(name.replace(".pdf", ""));
//將文件內容以字節數組的形式返回
byte[] bytes = file.getBytes();
contractPdf.setPdf(bytes);
} catch (IOException e) {
logger.error(e.getMessage());
}
logger.info(contractPdf.toString());
ModelAndView view = new ModelAndView();
view.setViewName("/index");
return view;
}
}
由於數據庫用的是sqlserver 建標的時候存流用的varbinary(max)類型,所以這裏ContractPdf 對象的pdf字段直接用byte[]就行了,是不是很方便呢
IOUtils
這個是 org.apache.commons.io 包中的,作爲一個工具類IOUtils 極大地方便了我們文件流的讀寫於複製
我這次主要用到了toByteArray方法
File[] files = new
File("C:\\Users\\ncpd241\\Desktop\\uprightContract").listFiles();
for (File file : files){
if (file.isFile() && file.exists()) { //判斷文件是否存在
ContractPdf contractPdf = new ContractPdf();
contractPdf.setContractCode(file.getName().replace(".pdf", ""));
contractPdf.setType("1");
InputStream is;
try {
is = new FileInputStream(file);
byte[] byteArray = IOUtils.toByteArray(is);
contractPdf.setPdf(byteArray);
} catch (IOException e) {
logger.error(e.getMessage());
}
} else {
logger.info("文件不存在,請檢查文件位置!");
}
}
是不是很方便的就把流轉成了字節數組呢,當然他還有很多很實用的方法比如
toString 返回字符串
toInputStream 返回輸入流
readLines 可以從流中讀取內容,並轉換爲String的list
copy 可以拷貝流
如果想了解更多的IOUtils相關的可以看看下面這篇博客,大佬寫的挺詳細的
https://blog.csdn.net/huanghanqian/article/details/82498724
已上是sqlserver的
---------------------------------------------------------------------------------------------------------------------------------------------------
在上mysql是遇到了一些小問題,記錄一下
最開始pdf字段用了varbinary類型,然後報錯,長度不夠,我把長度改成65535,發現mysql不允許,換成blob試試然後發現還是報長度不夠,然後看了下我的文件大小600kb,百度了下mysql的blob類型,改成mediumblob了,然後就ok了。
sqlserver中:
- binary(n):固定長度爲 n 字節,其中 n 值從 1 到 8,000 ,存儲空間爲 n 字節;
- varbinary( n | max):可變長度,n 的取值範圍爲 1 至 8,000,max 是指最大存儲空間是 2^31-1 個字節,即最大4GB;
mysql有四種blob類型:
- tinyblob:僅255個字符
- blob:最大限制到65K字節
- mediumblob:限制到16M字節
- longblob:可達4GB