目录
简述:
好久没用Java了,今天上课被问到这些,然后做了些整理:分享一下。
要将文件E盘中一个pdf文件复制到D盘中,E:\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf,D:/copytest.pdf
文件复制的四种方式(字节流):
主函数:
import java.io.*;
public class IOStreamDemo {
public static void main(String[] args) throws IOException {
long start=System.currentTimeMillis();//当前时间
// copy1("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时108956ms
// copy2("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时121ms
// copy3("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时418ms
// copy4("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时33ms
// copy5("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
// copy6("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
// copy7("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
copy8("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
long end=System.currentTimeMillis();//结束时间
System.out.println("耗时"+(end-start)+"ms");
}
方式一、使用字节流,逐个读写
/*
* 字节流,逐个字节读写
* */
private static void copy1(String sourse,String dest){
try {
FileInputStream fis=new FileInputStream(sourse);//创建文件输入流对象
FileOutputStream fos=new FileOutputStream(dest);//创建文件输出流对象
int ch;
while((ch=fis.read())!=-1)//fis.read()从流中读取一个字节
fos.write(ch);//将b转成字节数据,写入输出流
fis.close();//关闭流,释放资源
fos.close();//关闭流,释放资源
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
方式二、使用字节流,按字节数组读写
*//*
* 字节流,以字节数组的方式读写
* *//*
private static void copy2(String sourse,String dest){
try {
FileInputStream fis=new FileInputStream(sourse);
FileOutputStream fos=new FileOutputStream(dest);
byte[]bytes=new byte[1024];//构建字节数组
int len;
while((len=fis.read(bytes))!=-1)//fis.read(bytes)表示从输入流中读取bytes的长度个字符,返回len,即读取到的字节个数
fos.write(bytes,0,len);//将bytes中,从0开始len个字节写入输出流
fis.close();//关闭流
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
方式三、字节流,以Buffer的方式逐个读写
*//*
* 字节流,以Buffer的方式逐个读写
* */
private static void copy3(String sourse,String dest){
try {
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(sourse));//BufferedInputStream封装了FileInputStream
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(dest));
int ch;
while((ch=bis.read())!=-1)//从Buffer流中读取一个字节
bos.write(ch);//将读取到的字节写入输出流
bis.close();//关闭流对象
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
方式四、字节流,以Buffer的方式按字节数组读写
/*
* 字节流,以Buffer的方式按字节数组读写
* */
private static void copy4(String sourse,String dest){
try {
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(sourse));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(dest));
byte[]bytes=new byte[1024];//构建字符数组
int len;
while((len=bis.read(bytes))!=-1)//从输入流中读取bytes的长度个字符,返回读取到的字节长度
bos.write(bytes,0,len);//将bytes中,从0开始len个字节写入输出流
bis.close();//关闭流
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
文件复制的另外四种方式(字符流):
方式五、字符流,逐个
private static void copy5(String sourse,String dest)throws IOException{
InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
int ch;
while((ch=isr.read())!=-1)
osr.write((char)ch);
isr.close();
osr.close();
方式六、字符流,字符数组
private static void copy6(String sourse,String dest)throws IOException{
InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
char[]chars=new char[1024];//构建字符数组
int len;
while((len=isr.read(chars))!=-1)//fis.read(chars)chars,返回len,即读取到的字符个数
osr.write(chars,0,len);//将chars中,从0开始len个字节写入输出流
isr.close();//关闭流
osr.close();
}
方式七、字符流,缓冲,逐个
private static void copy7(String sourse,String dest)throws IOException{
InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
BufferedReader br=new BufferedReader(isr);
BufferedWriter bw=new BufferedWriter(osr);
int ch;
while((ch=br.read())!=-1)
bw.write((char)ch);
br.close();
bw.close();
}
方式八、字符流,缓冲,字符数组
private static void copy8(String sourse,String dest)throws IOException{
InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
BufferedReader br=new BufferedReader(isr);
BufferedWriter bw=new BufferedWriter(osr);
char[]chars=new char[1024];//构建字符数组
int len;
while((len=br.read(chars))!=-1)//fis.read(chars)chars,返回len,即读取到的字符个数
bw.write(chars,0,len);//将chars中,从0开始len个字节写入输出流
br.close();//关闭流
bw.close();
}
字节流与字符流
字节流的基本单位是字节,就会造成因为编码格式的不同造成表达的字符不同,
而字符流的基本单位是字符,即以指定的编码格式,将字节已经翻译成了一个个字符
eg:
字节流:(以△代表一个字节)
△,△,△,△,△,△,△,△…
字符流(编码格式:GBK)(英文一个字节,中文2个字节)
△,△,△,(△△),(△△),(△△)…
字符流(编码格式:utf-8)(英文一个字节,中文3个字节)
△,△,△,(△△△),(△△△),(△△△)…
那么,当文件中有中文时,如果按照字节逐个读写的话,将字节逐个翻译为字符就会造成,遇到中文时找不到与之对应的字符,就会造成乱码。
例如:
abc.txt以utf-8编码:
如果使用字节流逐个读写:
结果:(可以看到,一个字符占一个字节的英文正常,而占三个字节的中文,却被“翻译”成了三个字符,因此不能正常显示)
再如:
如果字节数组的方式,读写,就不会将原来在一起的3个字节分开(不考虑数组末尾将字节分开的情况)
结果:(就能正常显示)
特殊情况,数组长度末端刚好把中文字节分开
eg:中文的的字节在bytes中在地7,8,9位,而数组长度恰好将其分开,也会造成翻译错误
结果:
引入字符流:
如果引入字符流,因为其基本单位已经是字符,就不会造成中文的“翻译”错误
Eg.
结果:
另外一种情况:
因为abc.txt的编码格式是utf-8;如果创建字符流时,指定为GBK呢,也会造成“翻译错误”
因为utf-8的中文占3个字节,而GBK的中文占2个
例如:
结果:(原因不难解释,GBK只将中文的前两个字节“翻译”成了,它在GBK中表示的字,即“瀛”,后面剩一位,当成了英文,而英文中又没有改字符,因此出现?)
相互学习,共同进步,望批评指正!