定义
字符流是可以直接读写字符的IO流
字符流读取字符,就要先读取到字节数据, 然后转为字符,如果要写出字符,需要把字符转为字节在写出
实用性
如果是我们来对读取的字节进行转换的话,非常麻烦, 因为在储存的时候, 不同的文字占用的字节数是不同的, 就好像英文用1个字节,而中文用2个字节,对读取的内容解析就是非常痛苦的一键事情
不会出现读取到半个中文的情况
java在字符流中给我们提供了许多非常实用的方法, 比如一次读取文本的一行写出的时候可以将文本直接写入到本地文件,不需要转化为字节数组
使用
当程序需要跟文本进行交互的时候,推荐使用
当我们进行copy操作的时候, 无论是拷贝纯文本还是非文本极不推荐,非常有可以能出现乱码, 而且, 读取时字符流会有将字节转换成字符的动作,写入是会有讲字符转换成字节的动作,会降低性能
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
转换流
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();
}
内存流
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(); //将内存缓冲区中所有的字节存储在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();
}
字节流
小数组复制文件
字符流
读写流一般来收是分开操作的
字符缓冲流 : 操作方便
转换流 : 可以指定编码
内存流
一个专门用来存储字节的集合 ,操作类似于流
序列化流
将Java对象保存到本地, 等待时机合适, 再激活使用
保存到本地的对象必须实现Serializable接口
打印流
PrintStream : System.out 就是这个流
PrintWriter : 可以设置为自动刷新和写入换行符
文件上传三要素
提供form表单,method必须是post!
form表单的enctype必须是multipart/form-data
提供 input type="file" 类型长传输入
<%@ page language="java" pageEncoding="UTF-8"%>
文件上传
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+"目录不存在,需要创建");
//创建目录
file.mkdir();
}
//消息提示
String message = "";
try{
//使用Apache文件上传组件处理文件上传步骤:
//1、创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//2、创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//解决上传文件名的中文乱码
upload.setHeaderEncoding("UTF-8");
//3、判断提交上来的数据是否是上传表单的数据
if(!ServletFileUpload.isMultipartContent(request)){
//按照传统方式获取数据
return;
}
//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List
集合,每一个FileItem对应一个Form表单的输入项 List
list = upload.parseRequest(request); for(FileItem item : list){
//如果fileitem中封装的是普通输入项的数据
if(item.isFormField()){
String name = item.getFieldName();
//解决普通输入项的数据的中文乱码问题
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();
//创建一个文件输出流
FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
//创建一个缓冲区
byte buffer[] = new byte[1024];
//判断输入流中的数据是否已经读完的标识
int len = 0;
//循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
while((len=in.read(buffer))>0){
//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(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);
}
}
上述的代码虽然可以成功将文件上传到服务器上面的指定目录当中,但是文件上传功能有许多需要注意的小细节问题,以下列出的几点需要特别注意的
1、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。
2、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。
3、为防止一个目录下面出现太多文件,要使用hash算法打散存储。
4、要限制上传文件的最大值。
5、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。
文件下载
我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFileServlet,用于列出Web应用系统中所有下载文件
public class ListFileServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取上传文件的目录
String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
//存储要下载的文件名
Map
fileNameMap = new HashMap (); //递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中
listfile(new File(uploadFilePath),fileNameMap);//File既可以代表一个文件也可以代表一个目录
//将Map集合发送到listfile.jsp页面进行显示
request.setAttribute("fileNameMap", fileNameMap);
request.getRequestDispatcher("/listfile.jsp").forward(request, response);
}
public void listfile(File file,Map
map){ //如果file代表的不是一个文件,而是一个目录
if(!file.isFile()){
//列出该目录下的所有文件和目录
File files[] = file.listFiles();
//遍历files[]数组
for(File f : files){
//递归
listfile(f,map);
}
}else{
/**
* 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于: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函数库。jQuery是一个轻量级的"写的少,做的多"的JavaScript库。jQuery库包含以下功能:
HTML 元素选取
HTML 元素操作
CSS 操作
HTML 事件函数
JavaScript 特效和动画
HTML DOM 遍历和修改
AJAX
Utilities
网页中添加 jQuery
百度 CDN
jQuery语法
Query 语法是通过选取 HTML 元素,并对选取的元素执行某些操作。基础语法: $(selector).action()
美元符号定义 jQuery
选择符(selector)"查询"和"查找" HTML 元素
jQuery 的 action() 执行对元素的操作实例:
$(this).hide() - 隐藏当前元素
$("p").hide() - 隐藏所有
元素
$("p.test").hide() - 隐藏所有 class="test" 的
元素
$("#test").hide() - 隐藏所有 id="test" 的元素
元素选择器
id选择器
class选择器
$(document).ready(function(){
$("button").click(function(){
$(".test").hide();
});
});
click() 当按钮点击事件被触发时会调用一个函数。该函数在用户点击 HTML 元素时执行。在下面的实例中,当点击事件在某个
元素上触发时,隐藏当前的
元素:
$("p").click(function(){
$(this).hide();
});
dblclick()当双击元素时,会发生 dblclick 事件。dblclick() 方法触发 dblclick 事件,或规定当发生 dblclick 事件时运行的函数:
$("p").dblclick(function(){
$(this).hide();
});
mouseenter()当鼠标指针穿过元素时,会发生 mouseenter 事件。mouseenter() 方法触发 mouseenter 事件,或规定当发生 mouseenter 事件时运行的函数:
$("#p1").mouseenter(function(){
alert('您的鼠标移到了 id="p1" 的元素上!');
});
mouseleave()当鼠标指针离开元素时,会发生 mouseleave 事件。mouseleave() 方法触发 mouseleave 事件,或规定当发生 mouseleave 事件时运行的函数:
$("#p1").mouseleave(function(){
alert("再见,您的鼠标离开了该段落。");
});
mousedown()当鼠标指针移动到元素上方,并按下鼠标按键时,会发生 mousedown 事件。mousedown() 方法触发 mousedown 事件,或规定当发生 mousedown 事件时运行的函数:
$("#p1").mousedown(function(){
alert("鼠标在该段落上按下!");
});
mouseup()当在元素上松开鼠标按钮时,会发生 mouseup 事件。mouseup() 方法触发 mouseup 事件,或规定当发生 mouseup 事件时运行的函数:
$("#p1").mouseup(function(){
alert("鼠标在段落上松开。");
});
hover()hover()方法用于模拟光标悬停事件。当鼠标移动到元素上时,会触发指定的第一个函数(mouseenter);当鼠标移出这个元素时,会触发指定的第二个函数(mouseleave)。
$("#p1").hover(
function(){
alert("你进入了 p1!");
},
function(){
alert("拜拜! 现在你离开了 p1!");
}
);
focus()当元素获得焦点时,发生 focus 事件。当通过鼠标点击选中元素或通过 tab 键定位到元素时,该元素就会获得焦点。focus() 方法触发 focus 事件,或规定当发生 focus 事件时运行的函数:
$("input").focus(function(){
$(this).css("background-color","#cccccc");
});
blur()当元素失去焦点时,发生 blur 事件。blur() 方法触发 blur 事件,或规定当发生 blur 事件时运行的函数:
$("input").blur(function(){
$(this).css("background-color","#ffffff");
});
动画 animate() 方法
$("button").click(function(){
$("div").animate({
left:'250px',
opacity:'0.5',
height:'150px',
width:'150px'
});
});
设置内容 - text()、html() 以及 val()
我们将使用前一章中的三个相同的方法来设置内容:
text() - 设置或返回所选元素的文本内容
html() - 设置或返回所选元素的内容(包括 HTML 标记)
val() - 设置或返回表单字段的值