(85)字节流读写、缓冲区
来源:互联网 发布:阿里云ecs扩容 编辑:程序博客网 时间:2024/06/06 09:51
需求:想要操作图片数据,这就要用到字节流
字节流:InputStream OutputStream(写入)
字符流中用的是字符数组,在字节流中用的是字节数组
将字符串转换为字节数组:public byte[] getBytes()
将字符串转换为字符数组:public char[ ] toCharArray()
import java.io.*;public class FileDemo { public static void main(String[] args)throws IOException { //写 FileOutputStream fos=new FileOutputStream("fos.txt"); fos.write("abcde".getBytes());//不用刷新 fos.close();//虽然不刷新,但是得关资源 //读 FileInputStream fis=new FileInputStream("fos.txt"); System.out.println("-----------读的第一种方法----------"); //一个字节一个字节的读:read()方法 /*int num=0; while ((num=fis.read())!=-1) { System.out.println((char)num); } fis.close(); */ System.out.println("-----------读的第二种方法----------"); //字节数组的读read(byte[] b) /*byte[] buf=new byte[1024]; int len=0; while((len=fis.read(buf))!=-1) { System.out.println(new String(buf,0,len)); } fis.close(); */ System.out.println("-----------读的第三种方法----------"); // TODO Auto-generated method stub FileInputStream fis=new FileInputStream("fos.txt"); int len1=fis.available();//返回字节数 System.out.println(len1); byte[] buf1=new byte[len1];//定义一个刚刚好的缓冲区,因为已经知道长度了,无需循环 fis.read(buf1); fis.close(); //将所有的数据存入数组 //read(byte[]):从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 //这个方法完成了两件事情:1:将字符字节流中的数据放入字符数组中2:返回存入的字节长度 System.out.println(new String(buf1));
对比三种读的方式,第一种循环次数太多,速度太慢;第三种方式,虽然空间正好,因为现在操作的字节流,包括某些电影文件,若电影文件1G,在内存中设置这么大的数组是不合理的,所以一般还是用第二种方式
练习:复制一个图片
1,用字节读取流对象和图片关联
2,用字节写入流对象创建一个图片文件,用于存储获取到的图片数据
3,通过循环读写,完成数据的存储
4,关闭资源
注意:字符流只能用于处理文字数据,不能处理图片数据。
FileInputStream:可以用于读取诸如图像之类的原始字节流
import java.io.*;public class PictureCopy { public static void main(String[] args) { // TODO Auto-generated method stub FileOutputStream fos=null; FileInputStream fis=null; try { fos=new FileOutputStream("picture.png"); fis=new FileInputStream("C:\\picture.png"); int len=0; byte []buf=new byte[1024]; 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文件
import java.io.*;public class BufferaMp3Copy { public static void main(String[] args) { FileInputStream fis=null; FileOutputStream fos=null; BufferedInputStream bis=null; BufferedOutputStream bos=null; try{ fis=new FileInputStream("C:\\SBS.mp3"); fos=new FileOutputStream("SBS.mp3"); bis=new BufferedInputStream(fis); bos=new BufferedOutputStream(fos); int num=0; while((num=bis.read())!=-1) { bos.write(num); bos.flush(); } }catch(IOException e) { throw new RuntimeException("mp3复制失败"); } finally { try { if(bis!=null) bis.close(); }catch(IOException e) { throw new RuntimeException("原关闭失败"); } try { if(bos!=null) bos.close(); }catch(IOException e) { throw new RuntimeException("新关闭失败"); } } }}
自定义字节流的缓冲区
① 原理图(一次读一个数据(切记)):
定义数组:来充当缓冲区
定义指针:用来确定读取数组的哪号元素
定义计数器:用来确定是否要想数组(缓冲区中存入一批数组)
import java.io.*;public class MyBuffer { private InputStream in; private byte[] buf=new byte[1024]; private int pos=0,count=0; MyBuffer(InputStream in){ this.in=in; } //一次读一个字节(所以没有循环),从缓冲区(字节数组)获取 public int myRead()throws IOException{ //通过in对象读取硬盘上的数据,并存储在buf中 if(count==0) //在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&255; } return -1; } public void myClose()throws IOException { in.close(); }}
mp3数据都是由二进制数据组成的,读一个字节就是读8个二进制位,
11111111-11111000000000011111100000
11111111是-1
【负数的二进制是正数的二进制全取反然后加1。
1的二进制为00000001,取反11111110,加1,11111111】
当读取到11111111(1byte),就返回int(4byte),相当于类型提升。
byte:-1 —–>int:-1
11111111 —>11111111 11111111 11111111 11111111
这样提升完,还是-1,与判断没有数据的条件还是一样,仍然不能继续复制。
就可以补0,而不是补1,就避免了不能复制的情况同时原数据没发生变换(也是返回int类型的原因)
00000000 00000000 00000000 11111111
那么怎样补0呢?(取一个数的最低8位)
11111111 11111111 11111111 11111111
&00000000 00000000 00000000 11111111
00000000 00000000 00000000 11111111
11111111—->提升了一个int类型,还是-1的原因是在8个1的前面补1造成的。
那么只要在前面补0,既可以保留字节数据不变,也可以避免-1的出现。
* 上面的byte–>int类型转换理解后,还有个疑问,就是读出来的是int类型,复制出来的文件应该容量x4,但是从测试结果看出,并没有扩大容量,原因是?*
read类型提升,在write中是类型下降,即在API中写的将指定的字节写入此缓冲的输出流。
- (85)字节流读写、缓冲区
- android 字节流缓冲区 字节缓冲流 读写SD卡的内容
- 黑马程序员-字节流File读写操作_拷贝图片-mp3_自定义字节缓冲区
- 字节流的缓冲区(复制MP3)
- 自定义字节流缓冲区
- IO技术(二)字节流、字节流缓冲区
- IO流三:字节流文件读写操作、拷贝图片、带缓冲区的字节流、read()原理、读取键盘录入
- 模拟字节读取流缓冲区
- 字节输入流缓冲区 BufferedInputStreamDemo
- 字节流的缓冲区对象
- 用FileStream加byte[]字节数组缓冲区读写文件
- java 字节流与字符流的区别(缓冲区)
- 字节流--字节流缓冲区、字节缓冲流
- 浅谈JAVA字节流(读写文件)
- java字节流(读写文件)
- 自定义字节流缓冲区,演示缓冲区的工作原理
- IO流自定义字节流的缓冲区
- IO流--字节流缓冲区(BufferedOutputStream,BufferedInputStream)
- 一道android笔试题目
- 自用(Spring 配置文件 和详细笔记)
- poj 2299 Ultra-QuickSort (树状数组)
- Hibernate学习笔记
- 【二分图】poj 3020 Antenna Placement
- (85)字节流读写、缓冲区
- 洛谷P1028 数的计算
- 本地如何搭建FPT服务
- 版权声明
- 1017. The Best Peak Shape (35)
- vector
- HTML块级标签的补充
- 关于技术博客文章目录
- 链表的一些操作