黑马程序员------IO流(No.2)(字节流、InputStream、OutputStream、转换流、改变输入输出设备)

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

 

微笑字节流

InputStream OutputStream

import java.io.*;
class FileStream{
	public static void main(String[] args)throws Exception{
		readFile3();
	}
	//读取操作方法一
	public static void readFile1()throws Exception{
		FileInputStream fis = new FileInputStream("fos.txt");
		int ch = 0 ;
		while((ch=fis.read())!=-1){
			System.out.print((char)ch);
		}
		fis.close();
	}
	//读取操作方法二
	public static void readFile2()throws Exception{
		FileInputStream fis = new FileInputStream("fos.txt");
		byte[] buf = new byte[1024] ;
		int len = 0;
		while((len=fis.read(buf))!=-1){
			System.out.println(new String(buf,0,len));
		}
		fis.close();
	}
	//读取操作方法三
	public static void readFile3()throws Exception{
		FileInputStream fis = new FileInputStream("fos.txt");
		//定义一个刚刚好的缓冲区,不用循环。但是该文件不宜太大,否则内存溢出。
		byte[] buf = new byte[fis.available()] ;
		fis.read(buf);
		System.out.println(new String(buf));
		fis.close();
	}
	//写入方法
	public static void writeFile()throws Exception{
		FileOutputStream fos = new FileOutputStream("fos.txt");
		fos.write("aasfafa".getBytes());
		//这里可以不刷新也能存入。
		fos.close();
	}
}


拷贝一个图片。

 

思路:

1.用字节选取流对象和图片关联。

2.用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。

3.通过循环读写,完成数据的存储。

4.关闭资源

/*
复制一个图片
思路:
1.用字节选取流对象和图片关联。
2.用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3.通过循环读写,完成数据的存储。
4.关闭资源
*/
import java.io.*;
class CopyPic 
{
	public static void main(String[] args) 
	{
		//用字节选取流对象和图片关联。
		FileInputStream fis = null;
		//用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
		FileOutputStream fos = null;
		try
		{
			fis = new FileInputStream("qa.jpg");
			fos = new FileOutputStream("qb.jpg");
			int len = 0;
			byte[] buf = new byte[1024];
			//通过循环读写,完成数据的存储。
			while ((len = fis.read(buf))!=-1)
			{
				fos.write(buf,0,len);
			}
		}
		catch (IOException e)
		{
			System.out.println(e.toString());
		}
		finally
		{
			//关闭资源
			if(fis!=null){
				try
				{
					fis.close();
				}
				catch (IOException e)
				{
					System.out.println(e.toString());
				}
			}
			if(fos!=null){
				try
				{
					fos.close();
				}
				catch (IOException e)
				{
					System.out.println(e.toString());
				}
			}
		}
		
	}
}


演示avi的复制。通过缓冲区

import java.io.*;
/*
演示avi的复制。通过缓冲区
*/
class  CopyPic2{
	public static void main(String[] args)throws IOException{
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("002.avi"));
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("001.avi"));
		int by=0;
		while((by=bis.read())!=-1){
			bos.write(by);
		}
		bos.close();
		bis.close();
	}
}


 微笑键盘的录入问题

 

 
用键盘录入
System.out:对应的是标准输出设备,控制台。
System.in:对应的是标准输入设备,键盘。

/*
用键盘录入
System.out:对应的是标准输出设备,控制台。
System.in:对应的是标准输入设备,键盘。
*/
import java.io.*;
class ReadIn{
	public static void main(String[] args)throws IOException{
		InputStream in = System.in;
		StringBuilder sb = new StringBuilder();
		while(true){
			int ch = in.read();
			if(ch=='\r')
				continue;
			if(ch=='\n'){
				String s = sb.toString();
				if("over".equals(s))
					break;
				System.out.println(s.toString());
				sb.delete(0,sb.length());
			}else
				sb.append((char)ch);
			}
	}
}


 

 通过刚才的键盘录入一行数据并打印其字符串,我们发现其实就是读一行数据的原理。也就是readLine方法。

 

能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?

 

readLine方法是字符流BufferedReader类中的方法,而键盘录入的read方法是字符流InputStream的方法。那么能不能将字节流转成字符流然后再使用字符流中的readLine方法呢?

 

import java.io.*;
class TransStreamDemo{
	public static void main(String[] args)throws IOException{
		InputStream in = System.in;
		//将字节流转换成字符流对象,使用转换流:InputStreamReader
		InputStreamReader isr = new InputStreamReader(in);
		//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader。
		BufferedReader br = new BufferedReader(isr);
		StringBuilder sb = new StringBuilder();
		String s = null;
		while((s=br.readLine())!=null){
			System.out.println(s);
		}
	}
}

根据上面的程序,我们考虑到是不是向控制台输出也可以使用转换流呢?

根据文档,我们发现了Write的子类java.io.OutputStreamWriter

import java.io.*;
class TransStreamDemo{
	public static void main(String[] args)throws IOException{
		/*
		InputStream in = System.in;
		//将字节流转换成字符流对象,使用转换流:InputStreamReader
		InputStreamReader isr = new InputStreamReader(in);
		//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader。
		BufferedReader br = new BufferedReader(isr);
		*/
		//上面三个语句可以合成一个语句
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		/*
		OutputStream os = System.out;
		OutputStreamWriter osw = new OutputStreamWriter(os);
		BufferedWriter bs = new BufferedWriter(osw);
		*/
		//上面的三个语句可以合成一个语句
		BufferedWriter bs = new BufferedWriter(new OutputStreamWriter(System.out));

		StringBuilder sb = new StringBuilder();
		String s = null;
		while((s=br.readLine())!=null){
			bs.write(s);
			bs.newLine();
			bs.flush();
		}
	}
}



关于流操作的基本规律,我们可以做个总结:

避免流对象很多,不知道用哪个(很痛苦)。我们可以通过两个明确来完成。

 

1.明确源和目的。

源:输入流。InputStream Reader

目的:输出流。OutputStream  Writer

 

2.操作的数据是否是纯文本。

是:字符流。

不是:字节流。

 

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

通过设备来进行区分:

源设备:内存,硬盘,键盘

目的设备:控制台,内存,硬盘

 

 

需求:将键盘录入的数据保存到一个文件中。

这个需求中的源和目的都存在。

源:

InputStream Reader

是不是纯文本 是

设备:键盘。对应的对象System.in。

不死选择Reader吗?System.in对应的不是字节流吗?

为了操作键盘的文本数据方便,转成字符流,按照字符串操作是最方便的。

所以既然明确了Reader,那么就将System.in转成Reader。

用了Reader体系中转换流,InputStreamReader。

为了提高效率,使用BufferedReader。

 

目的:

OutputStream Writer

是否为纯文本?是,Writer。

设备:硬盘。一个文件,使用FileWriter。

需要提高效率吗?需要使用BufferedWriter。

--------------------------------------------------------------

扩展,想要把录入的数据按照指定的编码表(UTF-8)将数据存到文件中。

目的:OutputStream Writer

是否纯文本?是!Writer。

设备:硬盘。一个文件。使用FileWriter。

但是FilerWriter是使用默认的编码表。GBK

 

但是存储时,需要加入指定的编码表utf-8。而指定的编码表只有转换流可以指定 。

所以要使用的对象是OutputStreamWriter。

而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream。

import java.io.*;
class WriteToFile {
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new 
			OutputStreamWriter (new FileOutputStream("sendTo.txt"),"utf-8"));
		String s = null;
		while((s=br.readLine())!=null){
			bw.write(s);
			if("over".equals(s))
				break;
			bw.newLine();
			bw.flush();
		}
	}
}


改变标准输入输出设备:

static voidsetIn(InputStream in)
Reassigns the "standard" input stream.
static voidsetOut(PrintStream out)
Reassigns the "standard" output stream.

import java.io.*;
class WriteToFile {
	public static void main(String[] args) throws IOException{
		System.setIn(new FileInputStream("TransStreamDemo.java"));
		System.setOut(new PrintStream("hahh.txt"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter (System.out));
		String s = null;
		while((s=br.readLine())!=null){
			bw.write(s);
			if("over".equals(s))
				break;
			bw.newLine();
			bw.flush();
		}
	}
}


 

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

详情请查看:http://edu.csdn.net

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值