字节流

一、理解流的概念
流是对计算机中输入输出进行的抽象。流是指一连串流动的字符,是以先进先出方式发送信息的通道,在java中流的实现建立在四个抽象类的基础上:InputStream、OutputStream、Reader和Write。其中InputStream/OutputStream设计成输入/输出字节流类,而Reader/Writer设计为输入/输出字符流设计。字节流类和字符流类形成分离的层次结构。一般说来**,处理字符或字符串时应使用字符流类,处理字节或二进制文件对象时应用字节流类。**
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.println((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();
				}	
	
			}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值