黑马程序员——JAVASE-IO流(上)
来源:互联网 发布:输入字符串统计java 编辑:程序博客网 时间:2024/05/29 18:11
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! —
一、IO流概述
1、IO流概念
IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,Java用于操作流的类都在IO包中
2、流的分类
(1) 流按流向分为两种:输入流,输出流。
(2) 流按操作类型分为两种:
字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
字符流 : 字符流只能操作纯字符数据,比较方便。
3、IO流常用基类
字节流的抽象父类:InputStream,OutputStream
字符流的抽象父类:Reader,Writer
注意:这四个类的的子类名称都是以父类名作为子类名的后缀。
4、IO程序书写
(1) 使用前,导入IO包中的类
(2) 使用时,进行IO异常处理
(3) 使用后,释放资源
二、字节流
1、常用方法
(1) InputStream
read() 读取一个字节
read(byte[]) 读取若干(数组长度)字节
available() 获取可读的字节数
close() 关闭流, 释放资源
(2) OutputStream
write(int) 写出一个字节
write(byte[]) 写出数组中的所有字节
write(byte[],start,len);写出数组中的部分字节
close() 关闭流, 释放资源
2、常用子类
(1) InputStream
FileInputStream:文件读取流
BufferedInputStream:缓冲输入流
(2) OutputStream
FileOutputStream:文件写入流
BufferedInputStream:缓冲输出流
3、缓冲流的原理
(1) BufferedInputStream
BufferedInputStream内置了一个缓冲区(数组)
从BufferedInputStream中读取一个字节时
BufferedInputStream会一次性从文件中读取多个字节, 存在缓冲区中, 返回给程序一个,程序再次读取时, 就不用找文件了, 直接从缓冲区中获取
直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个
(2) BufferedOutputStream
BufferedOutputStream也内置了一个缓冲区(数组),程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中,直到缓冲区写满时,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。
4、读取文件
(1)创建FileInputStream对象,指定一个文件,文件必须存在,不存在则会抛出FileNotFoundException异常
(2) 使用read()方法可以从文件中读取一个字节. 如果读取到文件末尾会读到-1
(3) 读取结束后需要释放资源, 调用close()方法关闭输入流
示例:FileInputStream fis = new FileInputStream("xxx.txt"); //创建流对象,关联xxx.txt文件int b;while((b = fis.read()) != -1) { //将每次读到的结果赋值给b System.out.println(b);}fis.close();//关闭流,释放资源
5、写出文件
(1 ) 创建FileOutputStream对象, 指定一个文件. 文件不存在会创建新文件, 存在则清空原内容. 如果需要追加, 在构造函数中传入true.
(2) 使用write()方法可以向文件写出一个字节.
(3) 写出结束后同样需要调用close()
示例:FileOutputStream fos = new FileOutputStream("aaa.txt"); //创建流对象,关联aaa.txtfos.write(100); //写出数据的时候会将前面24个0去掉,写出的是一个字节fos.write(98);fos.write(99);fos.close(); //关闭流,释放资源
6、拷贝文件
(1) 拷贝1:从文件中逐个字节读取, 逐个字节写出, 但这样做效率非常低
//创建输入流对象,关联1.mp3FileInputStream fis = new FileInputStream("1.mp3"); //创建输出流对象,关联copy.mp3FileOutputStream fos = new FileOutputStream("copy.mp3"); int b;while((b = fis.read()) != -1)//将每次读到的赋值给b { fos.write(b); //将b中的字节写出去 } //关流,释放资源fis.close(); fos.close();
(2) 拷贝2:可以定义一个数组作为缓冲区, 一次读取多个字节装入数组, 然后再一次性把数组中的字节写出
//创建输入流对象,关联1.mp3FileInputStream fis = new FileInputStream("1.mp3"); //创建输出流对象,关联copy.mp3 FileOutputStream fos = new FileOutputStream("copy.mp3"); byte[] arr = new byte[1024 * 8]; //自定义数组int len;while((len = fis.read(arr)) != -1) //将数据读到字节数组中{ fos.write(arr, 0, len);//从字节数组中将数据写到文件上 //fos.write(arr);}//关流,释放资源fis.close(); fos.close();
(3) 拷贝3:定义一个大数组拷贝,数组和文件的字节个数一样大,不会造成内存的浪费,但如果定义的数组过,大有可能会导致内存溢出。
//fis.available();一次获取读的文件的大小FileInputStream fis = new FileInputStream("1.mp3");FileOutputStream fos = new FileOutputStream("copy.mp3");//虽然可以拷贝,但是在开发时不建议,有可能会导致内存溢出byte[] arr = new byte[fis.available()]; fis.read(arr);fos.write(arr);fis.close();
(4) 拷贝4:带缓冲区的拷贝
FileInputStream fis = new FileInputStream("致青春.mp3"); //创建输入流对象,关联致青春.mp3BufferedInputStream bis = new BufferedInputStream(fis); //对fis进行包装,内置一个8192大小的字节数组 FileOutputStream fos = new FileOutputStream("copy.mp3"); //创建输出流对象,关联copy.mp3BufferedOutputStream bos = new BufferedOutputStream(fos); //对fos进行包装,内置一个8192大小的字节数组int b;while((b = bis.read()) != -1) { //read一次会先将文件上的数据读到缓冲区中,再从缓冲区一个一个的赋值给b bos.write(b); //write一次,是将b中的字节数据写到缓冲区,缓冲区写满再一次写到文件上}bis.close(); //只需要关掉包装后的即可bos.close();
7、为什么read方法返回是int而不是byte类型呢?
因为如果读取的是视频文件或音频文件或图片文件等,在读取过程中很有可能会遇到11111111,也就是byte类型的-1,那么遇到-1程序就会停止读取,会漏掉文件,为了防止这种情况出现,把byte类型提升为int类型,在这个字节前补上24个0,把遇到的-1变成255,这样可以保证将整个文件读完
8、读中文
字节流只读中文有弊端,可能会出现半个中文
解决办法:
1、用字符流去读
2、将文件上的所有的字节数据都读到缓冲区中,然后在转换成字符串
FileInputStream fis = new FileInputStream("bbb.txt");byte[] arr = new byte[4];int len;while((len = fis.read(arr)) != -1) { System.out.println(new String(arr,0,len));}fis.close();
9、写中文
字节流是可以写字符串的
但是必须将字符串转换成字节数组写出去
FileOutputStream fos = new FileOutputStream("bbb.txt");fos.write("我要学习".getBytes());fos.close();
三、标准的异常处理代码
try
{
}
catch
{
}
finally
{
}
/*复制一个图片思路: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("c:\\2.bmp"); fis = new FileInputStream("c:\\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("写入关闭失败"); } } }}
- 黑马程序员——JAVASE-IO流(上)
- 黑马程序员—javaSE—IO流
- 黑马程序员——JAVASE-IO流(下)
- 黑马程序员-JAVASE入门( IO流 )
- 黑马程序员——JavaSE之IO流二
- 黑马程序员——JavaSE之学习IO流的心得(一)
- 黑马程序员——IO流(上)
- 黑马程序员——JAVASE-集合(上)
- 黑马程序员——Java基础->IO流(上)
- 黑马程序员----【javaSE基础】IO--字节流
- 黑马程序员----【javaSE基础】IO--字符流
- 黑马程序员-javaSE学习之IO流
- 黑马程序员 JavaSE-11 IO流
- 黑马程序员——JavaSE学习笔记---IO(第二部分,更新中)
- 黑马程序员——JavaSE学习笔记---IO(第一部分)
- 黑马程序员-javase-io(1)
- 黑马程序员-javase-io(2)
- 黑马程序员-javase-io(3)
- 模仿UIImageView
- OC中如何调试野指针异常(EXC_BAD_ACCESS(code = ....))
- 图片水印
- 图片裁剪
- 屏幕截图
- 黑马程序员——JAVASE-IO流(上)
- Markdown写文章血的教训,需谨记
- 51单片机学习笔记【四】——定时器和中断系统
- redhat 查询端口占用
- Apache Web Server -> httpd 的长连接配置
- 修改 Windows 8.1 的默认字体
- Leetcode #49 Anagrams
- 每天一个Linux命令-8(tar及解压缩相关命令)
- 算法导论 第二十二章:图的搜索