字节流

发表时间:2017-05-09 13:02:40 浏览量( 19 ) 留言数( 0 )

学习目标:

1、了解Java的历史

2、为什么要学习Java语言

3、端正学习态度


学习过程:

一、理解流的概念

流是对计算机系统中的输入输出进行的抽象。流是指一连串流动的字符,是以先进先出方式发送信息的通道,。在java中流的实现建立在四个抽象类的基础上:InputStream、OutputStream、Reader和Writer。其中InputStream/OutputStream 设计成输入/输出字节流类,而Reader/Writer设计为输入/输出字符流设计。字节流类和字符流类形成分离的层次结构。一般说来,处理字符或字符串时应使用字符流类,处理字节或二进制文件对象时应用字节流类。

attcontent/c72bc564-0a5b-47b6-a36d-c0ca94a1d694.png

InputStream、OutputStream、Reader和Writer这些都是抽象类,任何输入输出都是都可以抽象成为这几个流,流的来源可以是网络,硬盘等等,所以这些抽象类有很多不同的实现类。这里我们主要学习的是以硬盘作为流的来源和目的。输入和输出是以内存作为参照的,也就是凡是流入内存的就是输入,从内存流出的就是输出,记住这点,就不会混乱了。

二、文件字节流实现类

字节流是从InputStream和OutputStream派生出来的一系列类,这一系列流以字节(byte)为基本的处理单位,在命名特点上类名是通常以Stream结尾,如标准的FileInputStream、FileOutputStream、带缓存的BufferedOutputStream、BufferedInputStream等。

我们先看看输入流InputStream,它是一个抽象类,定义了Java流在处理字节输入数据的行为,因此所有的字节输入流都扩展于它。该类下的所有方法都有可能抛出IOException异常。常用的一些方法介绍如下:

int available()

          返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。

void close()

          关闭此输入流并释放与该流关联的所有系统资源。

void mark(int readlimit)

          在此输入流中标记当前的位置。

boolean markSupported()

          测试此输入流是否支持 mark 和 reset 方法。

abstract  int read()

          从输入流中读取数据的下一个字节。

int read(byte[] b)

          从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

int read(byte[] b, int off, int len)

          将输入流中最多 len 个数据字节读入 byte 数组。

void reset()

          将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。

long skip(long n)

          跳过和丢弃此输入流中数据的 n 个字节。

从这些方法上大致可以看出字节输入流的常规处理方法。

1、文件输入流FileInputStream。就是把硬盘中的文件内容读取到内存中,我们先在E:盘中新建一个abc.txt文件,并在文件中输入几个英文字符,然后我们再打印在控制台上,示例代码如下:

public void input() {
		// File file=new File("e://abc.txt");
		InputStream input = null;// 定义
		try {
			input = new FileInputStream("e://abc.txt");
			// 用于保存每次读取出来的数据(一个字节8位)
			int temp = 0;
			temp = input.read();//
			// 当文件读取到最后一个适合会返回-1;
			while (temp != -1) {
				// 输出出来
				System.out.print((char) temp);
				temp = input.read();// 继续读取
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				input.close();// 关闭文件,以释放资源
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

在main方法中调用这个方法,查看控制台是否能读入文件的内容并打印,这里要注意的是,文件流操作完毕后必须要关闭流,否则只要程序没有结束,这个文件会一直占用。

2、文件输出流FileOuputStream。就是把内存中的信息输出到硬盘指定的文件中。示例代码如下:

// 写入文件
	public void output() {
		try {
			// 释放追加信息
			OutputStream output = new FileOutputStream("e://abc.txt", true);
			/*output.write('I');//一个英文=一个字节
			output.write(' ');
			output.write('L');
			output.write('o');
			output.write('v');
			output.write('e');
			output.write(' ');
			output.write('Y');
			output.write('o');
			output.write('u');*/
			
			output.write('我');//一个汉字=2个字节
			output.write('爱');
			output.write('中');
			output.write('国');

			// 关闭文件
			// 清空内存缓存
			output.flush();
			output.close();

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

由上面的代码可见每次只能输出一个字节。我们尝试先输出普通的英文字符,打开abc.txt文件,查看是否已经把内容正确的输出到文件中。然后再尝试输出中文字符,结果发现中文发生了乱码,因为一个中文是使用两个字节保存的,可见字节流对字符的处理并不强大。

三、实例。

下面我们自己写一个实现文件复制功能的方法copy(String srcpath,String tarpath),然后我们尝试一下复制一张图片,看看能否复制成功。

public class StuFileStream {

	public static void main(String[] args) throws Exception {
		
		StuFileStream stream = new StuFileStream();
		stream.copy("e://P1080092.jpg", "d://aa.jpg");
	}

	// 复制
	public void copy(String srcpath, String tarpath) {
		//
		InputStream input = null;// 定义
		OutputStream output = null;
		try {
			input = new FileInputStream(srcpath);
			output = new FileOutputStream(tarpath);
			// 用于保存每次读取出来的数据(一个字节8位)
			int temp = 0;
			temp = input.read();//
			// 当文件读取到最后一个适合会返回-1;
			while (temp != -1) {

				// 写到目标文件里
				output.write(temp);
				temp = input.read();// 继续读取
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally{
			//关闭资源
			try {
				input.close();
				output.flush();
				output.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		}

	}

}

你可以自己拿一张jpg图片尝试复制,最终你可以在d:盘中见到这个图,并打开文件查看能否成功?最终应该可以复制成功。