黑马程序员-day19-IO流(字节流)

------- android培训java培训、期待与您交流! ----------
 

字节流
1.基本操作与字符流类相同
2.但它不仅可以操作字符,还可以操作其他媒体文件

字节流的缓冲区
同样是提高了字节流的读写效率。

字节流实例:

/*
字符流:
FileReader
FileWriter。

BufferedReader
BufferedWriter

字节流:
InputStream  OutputStream

需求,想要操作图片数据。这时就要用到字节流。
复制一个图片.
*/
import java.io.*;
class  FileStream{
	public static void main(String[] args) throws IOException{
		readFile_3();
	}

	public static void readFile_3()throws IOException{
		FileInputStream fis = new FileInputStream("fos.txt");
		
//		int num = fis.available();
		byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。

		fis.read(buf);

		System.out.println(new String(buf));

		fis.close();
	}


	public static void readFile_2()throws IOException{
		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 readFile_1()throws IOException{
		FileInputStream fis = new FileInputStream("fos.txt");

		int ch = 0;

		while((ch=fis.read())!=-1)
		{
			System.out.println((char)ch);
		}

		fis.close();
	}

	public static void writeFile()throws IOException{
		FileOutputStream fos = new FileOutputStream("fos.txt");
		

		fos.write("abcde".getBytes());

		fos.close();
		
	}
}

 

拷贝图片

/*
复制一个图片
思路:
1,用字节读取流对象和图片关联。
2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3,通过循环读写,完成数据的存储。
4,关闭资源。
*/

import java.io.*;
class  CopyPic{
	public static void main(String[] args) {
		FileOutputStream fos = null;
		FileInputStream fis = null;
		try{
			fos = new FileOutputStream("f:\\2.bmp");
			fis = new FileInputStream("f:\\1.bmp");

			byte[] buf = new byte[1024];

			int len = 0;

			while((len=fis.read(buf))!=-1){
				fos.write(buf,0,len);
			}
		}
		catch (IOException e){
			throw new RuntimeException("复制文件失败");
		}finally{
			try{
				if(fis!=null)
					fis.close();
			}
			catch (IOException e){
				throw new RuntimeException("读取关闭失败");
			}
			try{
				if(fos!=null)
					fos.close();
			}
			catch (IOException e){
				throw new RuntimeException("写入关闭失败");
			}
		}
	}
}



mp3的复制(通过缓冲区)

/*
演示mp3的复制。通过缓冲区。
BufferedOutputStream
BufferedInputStream
*/
import java.io.*;
class  CopyMp3{
	public static void main(String[] args) throws IOException{
		long start = System.currentTimeMillis();
		copy_2();
		long end = System.currentTimeMillis();

		System.out.println((end-start)+"毫秒");
	}

	public static void copy_2()throws IOException{
		MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("f:\\1.mp3"));
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("f:\\2.mp3"));
		
		int by = 0;

		//System.out.println("第一个字节:"+bufis.myRead());

		while((by=bufis.myRead())!=-1){
			bufos.write(by);
		}

		bufos.close();
		bufis.myClose();
	}

	//通过字节流的缓冲区完成复制。
	public static void copy_1()throws IOException{
		BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("f:\\0.mp3"));
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("f:\\1.mp3"));
		
		int by = 0;

		while((by=bufis.read())!=-1){
			bufos.write(by);
		}

		bufos.close();
		bufis.close();	
	}
}


 

自定义字节流的缓冲区

import java.io.*;

class MyBufferedInputStream{
	private InputStream in;

	private byte[] buf = new byte[1024*4];
		
	private int pos = 0,count = 0;
	
	MyBufferedInputStream(InputStream in){
		this.in = in;
	}

	//一次读一个字节,从缓冲区(字节数组)获取。
	public int myRead()throws IOException{
		//通过in对象读取硬盘上数据,并存储buf中。
		if(count==0){
			count = in.read(buf);
			if(count<0)
				return -1;
			pos = 0;
			byte b = buf[pos];

			count--;
			pos++;
			return b&255;
		}
		else if(count>0){
			byte b = buf[pos];

			count--;
			pos++;
			return b&0xff;
		}
		return -1;

	}
	public void myClose()throws IOException{
		in.close();
	}
}


结论:
字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。
因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.
那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。
所以,为了避免这种情况将读到的字节进行int类型的提升。
并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。
而在写入数据时,只写该int类型数据的最低8位。


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

实例:

/*
需求:
通过键盘录入数据。
当录入一行数据后,就将该行数据进行打印。
如果录入的数据是over,那么停止录入。
*/
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.toUpperCase());
				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 bufr = new BufferedReader(isr);


		//键盘的最常见写法。
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));
	
//		OutputStream out = System.out;
//		OutputStreamWriter osw = new OutputStreamWriter(out);
//		BufferedWriter bufw = new BufferedWriter(osw);
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

		String line = null;

		while((line=bufr.readLine())!=null){
			if("over".equals(line))
				break;
			bufw.write(line.toUpperCase());
			bufw.newLine();
			bufw.flush();
		}

		bufr.close();
	}
}


 

流操作的基本规律:
最痛苦的就是流对象有很多,不知道该用哪一个。
通过三个明确来完成。
1.明确源和目的。
 源:输入流。InputStream  Reader
 目的:输出流。OutputStream  Writer。
2.操作的数据是否是纯文本。
 是:字符流。
 不是:字节流。
3.当体系明确后,在明确要使用哪个具体的对象。
 通过设备来进行区分:
 源设备:内存,硬盘。键盘
 目的设备:内存,硬盘,控制台。

实例:

/*
需求:将一个文本数据打印在控制台上。要按照以上格式自己完成三个明确。
*/

class  TransStreamDemo2{
	public static void main(String[] args) throws IOException{
		System.setIn(new FileInputStream("PersonDemo.java"));

		System.setOut(new PrintStream("zzz.txt"));

		//键盘的最常见写法。
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));

		
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

		String line = null;

		while((line=bufr.readLine())!=null){
			if("over".equals(line))
				break;
			bufw.write(line.toUpperCase());
			bufw.newLine();
			bufw.flush();
		}

		bufr.close();
	}
}	


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值