黑马程序员 IO流

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

IO (input output) 流:

1. IO流用来处理设备之间的数据传输
2. Java对数据的操作是通过流的方式
3. Java用于操作流的对象都在IO包中
4. 流按操作数据分为两种:字节流与字符流。
    流按流向分为:输入流,输出流。


字节流的抽象基类:

InputStream ,OutputStream。

字符流的抽象基类:
Reader ,Writer。
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。如:InputStream的子类FileInputStream。Reader的子类FileReader。

这便是IO流中最主要的四个类,其实在原始的传输中只有字节流,而没有字符流。但是当只需要传输一个纯文本文件的时候,用字节流转换显得有些麻烦,所以才有了Reader、Writer这两个类。


字符流、字节流的缓冲区:
缓冲区的出现提高了对数据的读写效率。
对应类:
1.
 BufferedReader,BufferedWriter

2. BufferedInputStream,BufferedOutputStream

缓冲区要结合流才可以使用,在流的基础上对流的功能进行了增强,可以提高IO流的读写效率。


下面比较复制一个图片的速度来说明问题:

package test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test9 {
	//比较两种方法复制图片所用时间的多少
	public static void main(String[] args) throws Exception {
		long beginTime = System.currentTimeMillis();
		copy_1();
//		copy_2();
		long endTime = System.currentTimeMillis();
		System.out.println(endTime-beginTime);
	}
	
	//用缓冲区,但是一个一个的复制
	public static void copy_1(){
		//为了处理异常,必须定义在try外面
		BufferedInputStream bufin = null;
		BufferedOutputStream bufout = null;
		try {
			bufin = new BufferedInputStream(
					new FileInputStream("e:\\1.jpg"));
			bufout = new BufferedOutputStream(
					new FileOutputStream("e:\\2.jpg"));
			int ch = 0;
			while ((ch = bufin.read()) != -1)
				bufout.write(ch);
		} catch (Exception e) {
			throw new RuntimeException("复制出问题了!");
		}
		//用到close方法,也会抛出异常,必须处理
		finally{
			if(bufin!=null){
				try {
					bufin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bufout!=null){
				try {
					bufout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	//不用缓冲区,自己写一个字节数组用于赋值,直接声明抛出异常,简化书写
	public static void copy_2() throws Exception{
		FileInputStream fis = new FileInputStream("e:\\1.jpg");
		FileOutputStream fos = new FileOutputStream("e:\\2.jpg");
		
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=fis.read(buf))!=-1){
			fos.write(buf,0,len);
		}
		fis.close();
		fos.close();
	}
}
这个运行结果是copy_1方法用时285毫秒,而copy_2方法用时52毫秒。

显而易见,copy_2方法快的多,为何呢?不是copy_1用了缓冲区吗。其实缓冲区也就是加入了byte[] 数组的方式,来一次读一个数组,一次取一个数组,而copy_1是每次读一个字节,取一个字节,自然要慢上许多。


File类:
1. 用来将文件或者文件夹封装成对象

2. 方便对文件与文件夹的属性信息进行操作

3. File对象可以作为参数传递给流的构造函数。
File在IO流中经常用到,因为它对文件的操作非常方便,省去了很多麻烦,我们必须了解其中常用的一些方法。

创建: createNewFile(); 在指定位置创建文件,如果文件已存在,则不创建。

删除: delete(); 删除指定文件。 deleteOnExit(); 在程序退出时删除指定文件。

判断: exists(); 判断文件是否存在。 ifFile(); 是否为文件。 isDirectory(); 是否为目录。

获取: getName(); 获取文件名。 getPath(); 获取相对路劲。 getAbstractePath(); 获取绝对路劲。


下面展示一个获取一个文件夹中所有以.java结尾的文件,并打印其文件名和总个数。

package test;

import java.io.File;

public class Test10 {
	public static void main(String[] args) {
		//传入一个文件夹路径
		judgePath("E:\\JAVA\\javafile_save");
	}
	
	public static void judgePath(String path){
		File file = new File(path);
		//判断路劲输入是否正确,不正确则返回之
		if(!file.exists()){
			System.out.println("路径不存在");
			return;
		}
		//判断路劲是否为文件夹,不是则返回之
		if(!file.isDirectory()){
			System.out.println("输入的路径不是文件夹");
			return;
		}
		int count = 0;
		count = sopJavaFile(file,count);
		System.out.println("Java文件的总个数为:"+count);
	}
	
	//用递归的方法判断文件是否为文件夹,如果是,调用自身,不是,判断是否以.java结尾,是的就打印之
	public static int sopJavaFile(File file, int count){
		File[] files = file.listFiles();
		for(File f: files){
			if(f.isDirectory())
				count = sopJavaFile(f,count);
			else{
				String name = f.getName();
				if(name.endsWith(".java")){
					System.out.println(name);
					count++;
				}
			}
		}
		return count;
	}
}
打印结果的一部分:
TcpDemo3.java
TcpDemo4.java
UdpDemo.java
UdpDemo1.java
Demo.java
TcpPic.java
URLDemo.java
UserLogin.java
GetWeb.java
Person.java
RegexDemo.java
RegexTest.java
RegServer.java
Java文件的总个数为:116
这样就实现了打印一个文件夹中所有java文件的操作,在实际应用上File类文件也是如此,能方便快捷的实现对文件的各种操作。


其他IO流:

Properties:集合链接IO流的方法。

PriteStream,PriteWrite: 打印流,可以将各式各样的数据原样打印。

SequenceInputStream: 对多个流进行合并。

ObjectInputStream: 对象流,通过UID记录对象的值,可以存储、读取对象

PipedInputStream: 管道流,IO流+多线程 的结合,可以一边写入,一边读出

RandomAccessFile: 随机存储文件,该类不是IO体系中的子类,但是它是IO包中的成员,因为他具备读写功能。它内部封装了一个数组,而且通过指针对数组的元素进行操作。

DataInputStream: 数据流,可以直接对基本数据类型操作。


字符编码的方式:

中文主要是两种:GBK,UTF-8。

这里便涉及到了字符流和字节流的转化,其中2个最重要的转换流是:

InputStreamReader: 字符-->字节

OutputStreamWriter: 字节-->字符


在操作IO流的时候,只要掌握了一个规律,就能随心所欲的操作:

1. 明确源和目的

2. 操作的是否为纯文本文件

3. 当体系确定后,再明确要使用哪个具体的对象

只要明确了这三点,就能实现各种读取和写入操作。






---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值