定義
字符流是可以直接讀寫字符的IO流
字符流讀取字符,就要先讀取到字節(jié)數(shù)據(jù), 然后轉(zhuǎn)為字符,如果要寫出字符,需要把字符轉(zhuǎn)為字節(jié)在寫出
實用性
如果是我們來對讀取的字節(jié)進行轉(zhuǎn)換的話,非常麻煩, 因為在儲存的時候, 不同的文字占用的字節(jié)數(shù)是不同的, 就好像英文用1個字節(jié),而中文用2個字節(jié),對讀取的內(nèi)容解析就是非常痛苦的一鍵事情
不會出現(xiàn)讀取到半個中文的情況
java在字符流中給我們提供了許多非常實用的方法, 比如一次讀取文本的一行寫出的時候可以將文本直接寫入到本地文件,不需要轉(zhuǎn)化為字節(jié)數(shù)組
使用
當程序需要跟文本進行交互的時候,推薦使用
當我們進行copy操作的時候, 無論是拷貝純文本還是非文本極不推薦,非常有可以能出現(xiàn)亂碼, 而且, 讀取時字符流會有將字節(jié)轉(zhuǎn)換成字符的動作,寫入是會有講字符轉(zhuǎn)換成字節(jié)的動作,會降低性能
FileReader
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("d:\\aaa.txt");
char[] chs = new char[1024];
int len;
while((len=fr.read(chs))!=-1){
System.out.print(new String(chs,0,len));
}
fr.close();
}
FileWriter
public static void main(String[] args) throws Exception {
FileWriter fr = new FileWriter("d:\\ddd.txt");
fr.append('我');
fr.write('愛');
fr.write("你");
fr.flush();
fr.close();
}
字符緩沖流
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new FileReader("d:\\aaa.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\ddd.txt"));
int i ;
while((i=br.read())!= -1){
bw.write(i);
}
br.close();
bw.close();
}
LineNumberReader
public static void main(String[] args) throws Exception {
LineNumberReader lnr = new LineNumberReader(new FileReader("d:\\aaa.txt"));
String str;
System.out.println(lnr.getLineNumber());
lnr.setLineNumber(2);
while((str=lnr.readLine())!= null){
System.out.println(str+":"+lnr.getLineNumber());
}
lnr.close();
}
注意事項
行號默認從0開始
readLine方法每走一次, 行號+1
轉(zhuǎn)換流
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("d:\\aaa.txt"),"GBK"));
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("d:\\ddd.txt"),"UTF-8"));
String str ;
while ((str=br.readLine())!=null) {
System.out.println(str);
bw.write(str);
}
br.close();
bw.close();
}
內(nèi)存流
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i;
while((i = fis.read()) != -1) {
baos.write(i);
}
byte[] newArr = baos.toByteArray(); //將內(nèi)存緩沖區(qū)中所有的字節(jié)存儲在newArr中
System.out.println(new String(newArr));
System.out.println(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(newArr);
while ((i=bais.read())!=-1) {
System.out.println(i);
}
fis.close();
}
字節(jié)流
小數(shù)組復制文件
字符流
讀寫流一般來收是分開操作的
字符緩沖流? : 操作方便
轉(zhuǎn)換流 : 可以指定編碼
內(nèi)存流
一個專門用來存儲字節(jié)的集合? ,操作類似于流
序列化流
將Java對象保存到本地, 等待時機合適, 再激活使用
保存到本地的對象必須實現(xiàn)Serializable接口
打印流
PrintStream : System.out 就是這個流
PrintWriter : 可以設置為自動刷新和寫入換行符
文件上傳三要素
提供form表單,method必須是post!
form表單的enctype必須是multipart/form-data
提供 input type="file" 類型長傳輸入
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
? <head>
? ? <title>文件上傳</title>
? </head>
? <body>
? ? <form action="${pageContext.request.contextPath}/servlet/UploadHandleServlet" enctype="multipart/form-data" method="post">
? ? ? ? 上傳用戶:<input type="text" name="username"><br/>
? ? ? ? 上傳文件1:<input type="file" name="file1"><br/>
? ? ? ? 上傳文件2:<input type="file" name="file2"><br/>
? ? ? ? <input type="submit" value="提交">
? ? </form>
? </body>
</html>
public class UploadHandleServlet extends HttpServlet {
? ? public void doGet(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? ? ? ? ? //得到上傳文件的保存目錄韵吨,將上傳的文件存放于WEB-INF目錄下匿垄,不允許外界直接訪問移宅,保證上傳文件的安全
? ? ? ? ? ? ? ? String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
? ? ? ? ? ? ? ? File file = new File(savePath);
? ? ? ? ? ? ? ? //判斷上傳文件的保存目錄是否存在
? ? ? ? ? ? ? ? if (!file.exists() && !file.isDirectory()) {
? ? ? ? ? ? ? ? ? ? System.out.println(savePath+"目錄不存在归粉,需要創(chuàng)建");
? ? ? ? ? ? ? ? ? ? //創(chuàng)建目錄
? ? ? ? ? ? ? ? ? ? file.mkdir();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //消息提示
? ? ? ? ? ? ? ? String message = "";
? ? ? ? ? ? ? ? try{
? ? ? ? ? ? ? ? ? ? //使用Apache文件上傳組件處理文件上傳步驟:
? ? ? ? ? ? ? ? ? ? //1、創(chuàng)建一個DiskFileItemFactory工廠
? ? ? ? ? ? ? ? ? ? DiskFileItemFactory factory = new DiskFileItemFactory();
? ? ? ? ? ? ? ? ? ? //2漏峰、創(chuàng)建一個文件上傳解析器
? ? ? ? ? ? ? ? ? ? ServletFileUpload upload = new ServletFileUpload(factory);
? ? ? ? ? ? ? ? ? ? //解決上傳文件名的中文亂碼
? ? ? ? ? ? ? ? ? ? upload.setHeaderEncoding("UTF-8");
? ? ? ? ? ? ? ? ? ? //3糠悼、判斷提交上來的數(shù)據(jù)是否是上傳表單的數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? if(!ServletFileUpload.isMultipartContent(request)){
? ? ? ? ? ? ? ? ? ? ? ? //按照傳統(tǒng)方式獲取數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? //4、使用ServletFileUpload解析器解析上傳數(shù)據(jù)浅乔,解析結果返回的是一個List<FileItem>集合倔喂,每一個FileItem對應一個Form表單的輸入項
? ? ? ? ? ? ? ? ? ? List<FileItem> list = upload.parseRequest(request);
? ? ? ? ? ? ? ? ? ? for(FileItem item : list){
? ? ? ? ? ? ? ? ? ? ? ? //如果fileitem中封裝的是普通輸入項的數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ? if(item.isFormField()){
? ? ? ? ? ? ? ? ? ? ? ? ? ? String name = item.getFieldName();
? ? ? ? ? ? ? ? ? ? ? ? ? ? //解決普通輸入項的數(shù)據(jù)的中文亂碼問題
? ? ? ? ? ? ? ? ? ? ? ? ? ? String value = item.getString("UTF-8");
? ? ? ? ? ? ? ? ? ? ? ? ? ? //value = new String(value.getBytes("iso8859-1"),"UTF-8");
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(name + "=" + value);
? ? ? ? ? ? ? ? ? ? ? ? }else{//如果fileitem中封裝的是上傳文件
? ? ? ? ? ? ? ? ? ? ? ? ? ? //得到上傳的文件名稱,
? ? ? ? ? ? ? ? ? ? ? ? ? ? String filename = item.getName();
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(filename);
? ? ? ? ? ? ? ? ? ? ? ? ? ? if(filename==null || filename.trim().equals("")){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? //注意:不同的瀏覽器提交的文件名是不一樣的靖苇,有些瀏覽器提交上來的文件名是帶有路徑的席噩,如:? c:\a\b\1.txt,而有些只是單純的文件名贤壁,如:1.txt
? ? ? ? ? ? ? ? ? ? ? ? ? ? //處理獲取到的上傳文件的文件名的路徑部分悼枢,只保留文件名部分
? ? ? ? ? ? ? ? ? ? ? ? ? ? filename = filename.substring(filename.lastIndexOf("\\")+1);
? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取item中的上傳文件的輸入流
? ? ? ? ? ? ? ? ? ? ? ? ? ? InputStream in = item.getInputStream();
? ? ? ? ? ? ? ? ? ? ? ? ? ? //創(chuàng)建一個文件輸出流
? ? ? ? ? ? ? ? ? ? ? ? ? ? FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
? ? ? ? ? ? ? ? ? ? ? ? ? ? //創(chuàng)建一個緩沖區(qū)
? ? ? ? ? ? ? ? ? ? ? ? ? ? byte buffer[] = new byte[1024];
? ? ? ? ? ? ? ? ? ? ? ? ? ? //判斷輸入流中的數(shù)據(jù)是否已經(jīng)讀完的標識
? ? ? ? ? ? ? ? ? ? ? ? ? ? int len = 0;
? ? ? ? ? ? ? ? ? ? ? ? ? ? //循環(huán)將輸入流讀入到緩沖區(qū)當中,(len=in.read(buffer))>0就表示in里面還有數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ? ? ? while((len=in.read(buffer))>0){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //使用FileOutputStream輸出流將緩沖區(qū)的數(shù)據(jù)寫入到指定的目錄(savePath + "\\" + filename)當中
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? out.write(buffer, 0, len);
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? //關閉輸入流
? ? ? ? ? ? ? ? ? ? ? ? ? ? in.close();
? ? ? ? ? ? ? ? ? ? ? ? ? ? //關閉輸出流
? ? ? ? ? ? ? ? ? ? ? ? ? ? out.close();
? ? ? ? ? ? ? ? ? ? ? ? ? ? //刪除處理文件上傳時生成的臨時文件
? ? ? ? ? ? ? ? ? ? ? ? ? ? item.delete();
? ? ? ? ? ? ? ? ? ? ? ? ? ? message = "文件上傳成功脾拆!";
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }catch (Exception e) {
? ? ? ? ? ? ? ? ? ? message= "文件上傳失斅鳌!";
? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? request.setAttribute("message",message);
? ? ? ? ? ? ? ? request.getRequestDispatcher("/message.jsp").forward(request, response);
? ? }
? ? public void doPost(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? doGet(request, response);
? ? }
}
上述的代碼雖然可以成功將文件上傳到服務器上面的指定目錄當中名船,但是文件上傳功能有許多需要注意的小細節(jié)問題绰上,以下列出的幾點需要特別注意的
1、為保證服務器安全渠驼,上傳文件應該放在外界無法直接訪問的目錄下蜈块,比如放于WEB-INF目錄下。
2、為防止文件覆蓋的現(xiàn)象發(fā)生百揭,要為上傳文件產(chǎn)生一個唯一的文件名拘哨。
3、為防止一個目錄下面出現(xiàn)太多文件信峻,要使用hash算法打散存儲倦青。
4、要限制上傳文件的最大值盹舞。
5产镐、要限制上傳文件的類型,在收到上傳文件名時踢步,判斷后綴名是否合法癣亚。
文件下載
我們要將Web應用系統(tǒng)中的文件資源提供給用戶進行下載,首先我們要有一個頁面列出上傳文件目錄下的所有文件获印,當用戶點擊文件下載超鏈接時就進行下載操作述雾,編寫一個ListFileServlet,用于列出Web應用系統(tǒng)中所有下載文件
public class ListFileServlet extends HttpServlet {
? ? public void doGet(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? //獲取上傳文件的目錄
? ? ? ? String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
? ? ? ? //存儲要下載的文件名
? ? ? ? Map<String,String> fileNameMap = new HashMap<String,String>();
? ? ? ? //遞歸遍歷filepath目錄下的所有文件和目錄兼丰,將文件的文件名存儲到map集合中
? ? ? ? listfile(new File(uploadFilePath),fileNameMap);//File既可以代表一個文件也可以代表一個目錄
? ? ? ? //將Map集合發(fā)送到listfile.jsp頁面進行顯示
? ? ? ? request.setAttribute("fileNameMap", fileNameMap);
? ? ? ? request.getRequestDispatcher("/listfile.jsp").forward(request, response);
? ? }
? ? public void listfile(File file,Map<String,String> map){
? ? ? ? //如果file代表的不是一個文件玻孟,而是一個目錄
? ? ? ? if(!file.isFile()){
? ? ? ? ? ? //列出該目錄下的所有文件和目錄
? ? ? ? ? ? File files[] = file.listFiles();
? ? ? ? ? ? //遍歷files[]數(shù)組
? ? ? ? ? ? for(File f : files){
? ? ? ? ? ? ? ? //遞歸
? ? ? ? ? ? ? ? listfile(f,map);
? ? ? ? ? ? }
? ? ? ? }else{
? ? ? ? ? ? /**
? ? ? ? ? ? * 處理文件名,上傳后的文件是以uuid_文件名的形式去重新命名的鳍征,去除文件名的uuid_部分
? ? ? ? ? ? ? ? file.getName().indexOf("_")檢索字符串中第一次出現(xiàn)"_"字符的位置黍翎,如果文件名類似于:9349249849-88343-8344_阿_凡_達.avi
? ? ? ? ? ? ? ? 那么file.getName().substring(file.getName().indexOf("_")+1)處理之后就可以得到阿_凡_達.avi部分
? ? ? ? ? ? */
? ? ? ? ? ? String realName = file.getName().substring(file.getName().indexOf("_")+1);
? ? ? ? ? ? //file.getName()得到的是文件的原始名稱,這個名稱是唯一的艳丛,因此可以作為key匣掸,realName是處理過后的名稱,有可能會重復
? ? ? ? ? ? map.put(file.getName(), realName);
? ? ? ? }
? ? }
? ? public void doPost(HttpServletRequest request, HttpServletResponse response)
? ? ? ? ? ? throws ServletException, IOException {
? ? ? ? doGet(request, response);
? ? }
}
什么是jQuery氮双?
jQuery是一個JavaScript函數(shù)庫碰酝。jQuery是一個輕量級的"寫的少,做的多"的JavaScript庫戴差。jQuery庫包含以下功能:
HTML 元素選取
HTML 元素操作
CSS 操作
HTML 事件函數(shù)
JavaScript 特效和動畫
HTML DOM 遍歷和修改
AJAX
Utilities
網(wǎng)頁中添加 jQuery
<head>
<script src="jquery-1.10.2.min.js"></script>
</head>
百度 CDN
<head>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
</script>
</head>
jQuery語法
Query 語法是通過選取 HTML 元素送爸,并對選取的元素執(zhí)行某些操作≡焱欤基礎語法: $(selector).action()
美元符號定義 jQuery
選擇符(selector)"查詢"和"查找" HTML 元素
jQuery 的 action() 執(zhí)行對元素的操作實例:
$(this).hide() - 隱藏當前元素
$("p").hide() - 隱藏所有 <p> 元素
$("p.test").hide() - 隱藏所有 class="test" 的 <p> 元素
$("#test").hide() - 隱藏所有 id="test" 的元素
元素選擇器
id選擇器
class選擇器
$(document).ready(function(){
? $("button").click(function(){
? ? $(".test").hide();
? });
});
click() 當按鈕點擊事件被觸發(fā)時會調(diào)用一個函數(shù)碱璃。該函數(shù)在用戶點擊 HTML 元素時執(zhí)行。在下面的實例中饭入,當點擊事件在某個 <p> 元素上觸發(fā)時嵌器,隱藏當前的 <p> 元素:
$("p").click(function(){
$(this).hide();
});
dblclick()當雙擊元素時,會發(fā)生 dblclick 事件谐丢。dblclick() 方法觸發(fā) dblclick 事件爽航,或規(guī)定當發(fā)生 dblclick 事件時運行的函數(shù):
$("p").dblclick(function(){
$(this).hide();
});
mouseenter()當鼠標指針穿過元素時蚓让,會發(fā)生 mouseenter 事件。mouseenter() 方法觸發(fā) mouseenter 事件讥珍,或規(guī)定當發(fā)生 mouseenter 事件時運行的函數(shù):
$("#p1").mouseenter(function(){
alert('您的鼠標移到了 id="p1" 的元素上!');
});
mouseleave()當鼠標指針離開元素時历极,會發(fā)生 mouseleave 事件。mouseleave() 方法觸發(fā) mouseleave 事件衷佃,或規(guī)定當發(fā)生 mouseleave 事件時運行的函數(shù):
$("#p1").mouseleave(function(){
alert("再見趟卸,您的鼠標離開了該段落。");
});
mousedown()當鼠標指針移動到元素上方氏义,并按下鼠標按鍵時锄列,會發(fā)生 mousedown 事件。mousedown() 方法觸發(fā) mousedown 事件惯悠,或規(guī)定當發(fā)生 mousedown 事件時運行的函數(shù):
$("#p1").mousedown(function(){
alert("鼠標在該段落上按下邻邮!");
});
mouseup()當在元素上松開鼠標按鈕時,會發(fā)生 mouseup 事件克婶。mouseup() 方法觸發(fā) mouseup 事件筒严,或規(guī)定當發(fā)生 mouseup 事件時運行的函數(shù):
$("#p1").mouseup(function(){
alert("鼠標在段落上松開。");
});
hover()hover()方法用于模擬光標懸停事件情萤。當鼠標移動到元素上時鸭蛙,會觸發(fā)指定的第一個函數(shù)(mouseenter);當鼠標移出這個元素時,會觸發(fā)指定的第二個函數(shù)(mouseleave)紫岩。
$("#p1").hover(
function(){
alert("你進入了 p1!");
?? },
function(){
alert("拜拜! 現(xiàn)在你離開了 p1!");
?? }
);
focus()當元素獲得焦點時规惰,發(fā)生 focus 事件睬塌。當通過鼠標點擊選中元素或通過 tab 鍵定位到元素時泉蝌,該元素就會獲得焦點。focus() 方法觸發(fā) focus 事件揩晴,或規(guī)定當發(fā)生 focus 事件時運行的函數(shù):
$("input").focus(function(){
$(this).css("background-color","#cccccc");
});
blur()當元素失去焦點時勋陪,發(fā)生 blur 事件。blur() 方法觸發(fā) blur 事件硫兰,或規(guī)定當發(fā)生 blur 事件時運行的函數(shù):
$("input").blur(function(){
$(this).css("background-color","#ffffff");
});
動畫 animate() 方法
$("button").click(function(){
? $("div").animate({
? ? left:'250px',
? ? opacity:'0.5',
? ? height:'150px',
? ? width:'150px'
? });
});
設置內(nèi)容 - text()诅愚、html() 以及 val()
我們將使用前一章中的三個相同的方法來設置內(nèi)容:
text() - 設置或返回所選元素的文本內(nèi)容
html() - 設置或返回所選元素的內(nèi)容(包括 HTML 標記)
val() - 設置或返回表單字段的值