说明:
图片不是字符,而是字节,是二进制的数据,不能用字符流来处理图片等字节数据(不会报错,不会出异常)
FileInputStream的使用:
使用FileInputStream不能读取文本文件的测试
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
FileInputStream fi=null;
try{
//1.造文件
File f=new File("hello1.txt");
//2.造流
fi=new FileInputStream(f);
//3.读数据
byte[] bytes=new byte[5];
int len;//记录每次读取的字节个数
while((len=fi.read(bytes))!=-1) {
String str = new String(bytes, 0, len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally{
//4.关闭资源
try {
if(fi!=null)
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*但能够正确输出文件内容:
I have a dream!
You need to have a dream!
*/
分析:
因为英文字符在UTF-8或者JDK还是用一个字节存的(一个字节就足够存下了)数字也是用一个字节存的,所以用字节数组,每个元素是一个字节也都可以
但如果文件内容中有汉字之类的(用一个字节存不下,在UTF-8使用三个字节来存)就不可以了,会出现乱码(但可能会出现能够挪出三个字节的位置放一个汉字)
所以其中可能会出现正常的汉字
但如果使用FileReader的方式,无论是read(),还是read(char[])都没有问题
文本文件要用字符流去读,不要用字节流
总结:
对于文本文件(.txt,.c,.cpp,.java)使用字符流处理,对于非文本文件(.mp3,.mp4,.avi,.doc,.ppt……)使用字节流处理
.c:表示用C语言写的
.cpp:表示用cpp写的
.mp3:表示音频文件
.mp4:表示视频文件
.avi:表示视频文件
.doc:表示文档文件
.ppt
针对非文本文件的数据都可以使用FileInputStream和FileOutputStream
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
FileInputStream fi=null;
FileOutputStream fo=null;
try{
//1.造文件
File f=new File("图.jpg");
File f1=new File("fun.jpg");
//2.造流
fi=new FileInputStream(f);
fo=new FileOutputStream(f1);
//3.复制的过程,利用字节数组
byte[] bytes=new byte[5];
int len;//记录每次读取的字节个数
while((len=fi.read(bytes))!=-1) {
fo.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally{
//4.关闭资源
try {
if(fi!=null)
fi.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fo!=null)
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
将指定路径下文件的复制操作包装成函数,并得到复制操作花费了多少时间
包装成的函数为:
public void copyFile(String srcpath, String desPath) {//srcpath表示从什么地方开始复制,desPath表示复制到什么地方
FileInputStream fi = null;
FileOutputStream fo = null;
try {
//1.造文件
File f = new File(srcpath);
File f1 = new File(desPath);
//2.造流
fi = new FileInputStream(f);
fo = new FileOutputStream(f1);
//3.复制的过程,利用字节数组
byte[] bytes = new byte[1024];//每次最多往里面写入1024个字节,数字不是越大越好,数字越大,虽然交互的次数会变少,但是交互的内存会多一些,最好根据文件的类型(视频可以稍微大一点,一般写成1024)设置一个适中的值
int len;//记录每次读取的字节个数
while ((len = fi.read(bytes)) != -1) {
fo.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭资源
try {
if (fi != null)
fi.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fo != null)
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//测试花费的时间的操作为:
long start=System.currentTimeMillis();
String srcpath="";//存放文件的路径
String desPath="";//存放文件的路径
copyFile(srcPath,dexPath);
long end=System.currentTimeMillis();//返回的是毫秒值
System.out.println("复制操作花费的毫秒数为:"+(end-start));
注意:如果把上面的1024改成5,给的是两个文本文件的路径,能够实现文本文件的复制(写成5都能实现,那写成1024当然能够实现)
原因:我们上次出现乱码的原因是我们在控制台进行了输出,而这次是直接进行复制,没有在控制台输出
字节流就相当于是搬运工,不管是文本文件还是非文本文件底层都是二进制,如果不在内存层面进行转化(即在内存进行读取)(即用String再把String的内容输出),打开文件是不会出现乱码的
如果只是对文本文件进行复制,用字节流也行,当然最好用字符流
非文本文件进行复制只能用字节流,不能用字符流