这一讲就是JAVA中的I/O流的一部分内容,当然,跟前面一样,咱们浅尝辄止,需要深入了解的推荐大家看一本JAVA核心技术 这本书讲的比较深入也很全面。
第一节 I/O流简介
流的本质是数据传输。
流分为两类主要:字符流和字节流
第二节 文件操作File类
先讲两个比较经典的用法就是创建文件和监测文件是否创建成功:
public class no1{
public static void main(String[] args) throws IOException {
File file = new File("d://hhh");//创建一个文件
boolean b = file.mkdirs();//创建虚拟目录
if(b){
System.out.println("successful!");
file = new File("d://hhh//hh.txt");
boolean a = file.createNewFile();//检测是否创建文件成功?
if(a){
System.out.println("sucessful,too!");
}
}else{
System.out.println("false!");
}
}
}
里面的注释都很清楚,作用就是在本地电脑的D盘创建了一个相应的文件,并在文件里面创建了一个文本文档,之所以会惊醒if判断,是因为这个是可能出现错误的,而且这个检测是否创建成功的这个方法还会抛出异常,可以使用TRY或者直接Throw都可以。
下面一个方法就是删除文件了,比较简单,就是文件对象名点delete()方法,但是会出现一个问题,就是有的时候文件删的掉,有的时候删不掉,经过多次尝试,发现因为当前文件正在被占用所以导致无法删除。在写程序的时候咬住以这个问题,但是一般不会遇到,毕竟没有谁创建一个文件正在运行中就要删了,感觉脑子有问题。删除文件目录的时候,文件目录下面必须为空,不能有任何的文件存在。
public static void main(String[] args) throws IOException {
File file = new File("d://hhh//hh.txt");
boolean aa = file.delete();
System.out.println(aa);
}
然后是遍历一个目录下的一级文件,什么叫做一级文件,就是直接在里面的不区分类型的文件。
public static void main(String[] args) throws IOException {
File file = new File("d://hhh");
//遍历一个文件目录下的所有文件
File[] files = file.listFiles();
for(int a = 0;a<files.length;a++)
System.out.println(files[a]);
}
那么问题来了,大家想不想知道如何便利所有的文件呢,而不是有的是文件目录,有的是文件?我们自己编写一个listFile()方法就可以实现这些!
//改写遍历文件的方法,一层一层全部遍历出来
public static void listFile (File f){
if(f!=null){
if (f.isDirectory()){//文件如果是目录
File fi[] = f.listFiles();
if(fi!=null)
for(int a = 0;a<fi.length;a++)
listFile(fi[a]);
else
System.out.println(f);
}
}
}
第三节 流的典型
1、InputStream() 把硬盘上的文件读取到内存中,也就是最简单的输入流:硬盘——>内存
大家要注意几点地方,首先读取的文件要加上后缀名.txt。
public static void main(String[] args) throws IOException {
File f = new File("D://hhh//1.txt");
InputStream io = new FileInputStream(f);//实例化输入流
byte b[] = new byte[1024];
io.read(b);
io.close();//关闭输入流
System.out.println(new String(b));
}
但是这样会出现最后的没有存上的字节的读出来就是乱码,怎么解决呢,自然而然时提前获取文件字节数,然后按照大小创建数组,既节省空间,有防止乱码。
int fl = (int)f.length();//提前获取文件大小
上面的都是一批一批的读取,那么我们想一个一个的读就要:
public static void main(String[] args) throws IOException {
File f = new File("D://hhh//1.txt");
InputStream io = new FileInputStream(f);//实例化输入流
int fl = (int)f.length();//提前获取文件大小
byte b[] = new byte[fl];
int tem = 0;
int len = 0;
while((tem = io.read())!= -1){//当读到最后的时候就会出现-1
b[len++] = (byte)tem;
}
io.close();//关闭输入流
System.out.println(new String(b));
}
2、outputStream()输出流
首先我们讲的是覆盖的方式,就是直接把原文件中的内容覆盖
public static void main(String[] args) throws IOException {
File f = new File("D://hhh//1.txt");
OutputStream out = new FileOutputStream(f);
String a = "fdihnfjdnkfbudfdjkdniv";
byte[] b = a.getBytes();
out.write(b);
out.close();
}
那当我们想在已经有的内容里面添加的话,我们就要用另外一种方法了:
OutputStream out = new FileOutputStream(f,true);
后面加一个true就可以在后面追加
3、BufferedInputStream()和BufferedOutputStream()
缓冲其实就是一个用来暂存的东西,举个例子来说,我们的长江三峡水库就是一个缓冲,这样可以防止水流大量涌来的时候导致下游泛滥成灾害!
我们先来测试一个关键问题,那就是用无缓冲的流和有缓冲的流到底有什么区别?
我们写一个利用无缓冲的输入输出流实现文件从D盘复制到F盘的操作:
//非缓冲
public static void stream() throws Exception{
InputStream io = new FileInputStream("D://hhh//1.txt");
OutputStream out = new FileOutputStream("F://LOL//ll.txt");
int b = 0;
long startTime = System.currentTimeMillis();//记录开始的时间,即程序运行到此处的时间
while((b = io.read())!=-1){
out.write(b);
}
io.close();
out.close();
System.out.println("系统花费时间:"+(System.currentTimeMillis()-startTime));
}
我们可以看到,花费的时间是34073ms,可以说时间很长
那么有缓冲的时候又会变成什么样子呢?
//缓冲
public static void stream() throws Exception{
BufferedInputStream io = new BufferedInputStream(new FileInputStream("D://hhh//1.txt"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("F://ll.txt"));
int b = 0;
long startTime = System.currentTimeMillis();//记录开始的时间,即程序运行到此处的时间
while((b = io.read())!=-1){
out.write(b);
}
io.close();
out.close();
System.out.println("系统花费时间:"+(System.currentTimeMillis()-startTime));
}
时间变成了158ms。
那么缓冲是怎么回事呢。相当于在内存中开辟了一个内存空间——缓冲区。如果来不及写或者数量太大,就先一次性放入缓冲区,然后写读都从里面拿。
新人上路,望老司机指点迷津 QQ815884631