黑马程序员_IO流操作1

<span style="font-family: Arial, Helvetica, sans-serif;">       ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------</span>

       在学习Java的SE基础部分时,一重要知识点就是IO流操作。这是因为流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称

为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

       Java中IO流可以根据处理数据类型的不同分为:字符流和字节流;根据数据流向不同分为:输入流和输出流 。

      那么什么时候用字符流,什么时间用字节流呢,通过学习和自己的理解,简单的总结为一句话,所以传输都可以用字节流,文字用字符流,其他(图片、文件)用字节流处

理。这只是我个人的理解,如果有误还请好心的你指正。

1.输入字节流InputStreamIO 中输入字节流的继承图可见上图,可以看出:

InputStream 是所有的输入字节流的父类,它是一个抽象类。ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。

OutputStream 是所有的输出字节流的父类,它是一个抽象类。ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。

    

           

         这张图是Java流操作有关的类或接口。下面这张图将详细解释Java流类结构:


         话不多说,上代码,首先看看字节流吧。代码的思想也是由浅入深,最终变成常用形式。

package com.vince.bytestream;
/**
 * 字节流输入
 * */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamDemo {

	/**
	 * 字节输入流读取方式一:每一次读取一个字节
	 * */
	public static void read1(){
		try {
			//构造一个字节输入流对象
			InputStream in = new FileInputStream("e:\\1.txt");
			int b = -1;//-1表示没有数据
			while((b=in.read())!=-1){ 
				System.out.print((char)b);
			}
			//关闭
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 字节输入流读取方式二:一次性读取所有字节
	 * */
	public static void read2(){
		try {
			//构造一个字节输入流对象
			File f = new File("e:\\1.txt");
			InputStream in = new FileInputStream(f);
			//根据文件的大小构造字节数组
			byte[] bytes = new byte[(int)f.length()];
			int len = in.read(bytes);
			System.out.println(new String(bytes));
			System.out.println("len="+len);
			//关闭
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 字节输入流读取方式三:每次读取指定大小的字节
	 * */
	public static void read3(){
		try {
			//构造一个字节输入流对象
			File f = new File("e:\\1.txt");
			InputStream in = new FileInputStream(f);
			//根据文件的大小构造字节数组
			byte[] bytes = new byte[10];
			int len = -1;//每次读取的实际长度
			StringBuilder sb = new StringBuilder();
			while((len = in.read(bytes))!=-1){
				sb.append(new String(bytes,0,len));
				//sb.append(new String(bytes));如果用这个会有问题,
				//数组内容是覆盖,最后一次可能用不了10个,只覆盖3个
				//那么后面6个将不是我们需要的愿内容
			}
			//关闭
			in.close();
			System.out.println(sb);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		read2();
		//System.out.println("success");
	}
}

package com.vince.bytestream;
/**
 * 字节流输出
 * */
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class OutputStreamDemo {

	
	/**
	 * 字节输出流的方式一:每次输出一个字节
	 * */
	public static void write1(){
		try {
			//创建一个文件字节输出流
			OutputStream out = new FileOutputStream("e:\\1.txt");
			String info = "Hello,IO";
			byte[] bytes = info.getBytes();
			for(int i=0;i<bytes.length;i++){
				out.write(bytes[i]);//向文件中输出
			}
			//关闭流
			out.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace(); 
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 字节输出流的方式二:每次输出指定大小的字节
	 * */
	public static void write2(){
		try {
			//创建一个文件字节输出流
			OutputStream out = new FileOutputStream("e:\\1.txt");
			String info = "Hello,xiaobai";
			byte[] bytes = info.getBytes();
			out.write(bytes);//输出一个字节数组
			//关闭流
			out.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace(); 
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 字节输出流的方式二:每次输出指定大小的字节.追加
	 * */
	public static void write3(){
		try {
			//创建一个文件字节输出流
			OutputStream out = new FileOutputStream("e:\\1.txt");//("e:\\1.txt,true")表示追加
			String info = "Hello,xiaobai";
			byte[] bytes = info.getBytes();
			out.write(bytes,0,5);//输出一个字节数组中指定范围的字节
			//关闭流
			out.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace(); 
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	
	public static void main(String[] args) {
		//write1();
		//write2();
		write3();
		System.out.println("success");
	}

}
<span style="white-space:pre">	</span>字节流看完了,接下来我们看看字符流。
<span style="white-space:pre">	</span>字节流与字符流有什么区别呢?对于一个纯文本文件,字符流可以读取,<span style="font-family: Arial, Helvetica, sans-serif;">可以如果用字节流对UTF-8或Uicode进行读取可能会出现乱码,因此就有了专门对文本操作的字节流。字节流分为两类:Reader和Writer。</span>
 
<span style="white-space:pre">	在上面的继承关系图中可以看出:
</span>
<span style="white-space:pre">	</span>Reader
<span style="font-family: Arial, Helvetica, sans-serif;">		1、Reader 是所有的输入字符流的父类,它是一个抽象类。</span><span style="white-space:pre">
	2、CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。
	3、BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。
	4、FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。
	5、InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明	显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类	使用一致。后面会有Reader 与InputStream 的对应关系</span>
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>Writer
<span style="white-space:pre">	1、Writer 是所有的输出字符流的父类,它是一个抽象类。
	2、CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写	</span>   <span style="white-space:pre">入数据,
	3、BufferedWriter 是一个装饰器为Writer 提供缓冲功能。
	4、PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
	5、OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCod	</span>   <span style="white-space:pre">e)。功能和使用和OutputStream 极其类似,后面会有它们的对应图。</span>
</pre><pre name="code" class="java"><span style="white-space:pre">	</span>通过下面的代码,加深Reader和Writer的使用吧。读者可以把以下代码复制下来到自己的java工具中运行调试。
<pre name="code" class="java"><span style="white-space:pre">package IO字符流;


import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;	</span>
<span style="white-space:pre"></span><pre name="code" class="java">public class The_1_Reader {

	public static void main(String[] args) {
		//创建一个文件读取对象,和指定名称的文件相关联。
		//要保证该文件是已经存在的,如果不存在,会发生异常
		FileReader fr = null;
		try {
			fr = new FileReader("e:\\text1.txt");
			//调用读取流对象的read方法
//			int ch;
			//一次读一个字符,而且会依次往下读
//			ch = fr.read();
//			System.out.println("ch="+(char)ch);
			int len = -1;
			
			while((len = fr.read())!=-1){
				System.out.print("len="+(char)len);//注意print 如果println数据超出1024会换行
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
 
 


package IO字符流;

import java.io.FileWriter;
import java.io.IOException;

/**
 * IO流
 * 		流按操作数据分为两种:字节流与字符流
 * 		流按流向分为:输入流、输出流
 * 
 * 	字节流的抽象基类
 * 		InputStream,OutputStream
 *  字符流的抽象基类
 *  	Reader,Writer
 *  这四个类派生出来的子类名称都是以其父类名作为子类名的后缀,前缀名为该类的功能
 *  	如:InputStream 的子类 FileInputStream
 *         Reader  的子类  FileReader
 *   
 * */

public class The_1_Writer {

	public static void main(String[] args) {
		//在外面进行引用,在try中进行初始化
		FileWriter fw = null;
		try {
			//创建一个FileWriter对象。该对象已被初始化就必须要明确被初始化的文件
			//而且该文件会被创建到指定的目录下,如果该目录下已有同名文件,将被覆盖
			//其实该步就是在明确数据存放的目的地。
			 fw = new FileWriter("e:\\text1.txt");

			//调用write()方法,将字符串写入到流中
			fw.write("abcde");
			//刷新流对象中缓冲的数据。
			//将数据刷到目的地中。
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			try {
				//关闭流资源,但是关闭前会刷新一次内部的缓冲中的数据
				//将数据刷新到目的地中
				//和flush区别:flush刷新后,流可以继续使用,close刷新后,会关闭流
				if(fw!=null)
					fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值