java输入与输出流
来源:互联网 发布:手机蓝牙打印机软件 编辑:程序博客网 时间:2024/05/02 02:13
概述
从14年10月份开始工作,到今天做Android已经两年半了。可是到现在也没搞清楚Java的I/O机制,痛定思痛,觉得好好整理一下。古人云“格物致知”,今天就好好格一格I/O机制吧!
常见问题
什么是流
“流”是一连串流动的字符,同时也说明了数据传输的一种状态:“均匀与连续”。java使用“流”进行数据传输。而传输的双方一般是“你的程序”和“设备(手机)”。
输入和输出流
根据流的方向,可以分为输入流和输出流。流的输入(Input)和输出(Output)是以应用程序为参考中心的。输入流就是从设备流入到应用程序,也即常说的读(Read);输出流就是从应用程序流到设备,也即我们常说的写(Write)。
原理图如下:
注:输入流命名规则是包含Input或Reader,如InputStream、BufferedReader;输出流命名规则是包含Output或Writer,如OutputStream、BufferedWriter。
字节流和字符流
数据传输的基本单位是字节(bytes),但1个字节是8位,表示范围是0-255。面对诸多汉字,1个字节很明显是不足的。所以生成了一种新的单位:字符,而字符和字节之间的映射关系就是Unicode。在java中1个字符等于2个字节。根据流的数据类型,可分为字节流和和字符流。
字节流和字符流的区别
1. 读写单位:字节流处理的基本单元是字节;字符流处理的基本单元是Unicode码,2个字节
2. 处理对象:字节流能处理所有类型的数据(图片,视频,音频等),字符流只能处理字符型数据(字符串,纯文本文档)
3. 是否缓存:字符流传输之前要先经过Unicode转换成字节流,批量转换后的字节流存储到缓存当中(提示效率),然后再进行读写。字节流则不用缓存(字节流本身是不使用字节流的,但是如果想提升效率,可以自定义缓存区)。
注:字节流一般命名规则是以Stream结尾,如InputStream或OutputStream;字符流一般命名规则是以Reader或Writer结尾。如BufferedReader、BufferedWriter。
节点和处理流
根据流是否直接与数据源相连,可以划分为节点流和处理流。节点流是可以直接从/向数据源(设备,硬盘,内存等)读/写数据;处理流是对一个已存在的流的连接、封装和处理。
注:处理流命名规则是包含buffered,如BufferedInputStream、BufferedReader。
介绍
I/O家族谱系
根据操作的数据类型,分为字节流和字符流;根据数据的流向,又分为输入流和输出流;根据功能,分为节点流和处理流。
InputStream和OutputStream
字节流处理的抽象基类是InputStream和OutputStream。InputStream是字节输入流,OutputStream是字节输出流。
Reader和Writer
字符流处理的抽象基类是Reader和Writer。Reader是字符输入流,Writer是字符输出流。
实战演示
介绍的差不多了,接下来就是实战演示了。
1.从本地读取图片
1. 读取说明数据流是从设备到应用,因此使用输入流,那就是InputStream或Reader
2. 操作的数据对象是图片,使用字节流的话效率较高(不用经由Unicode转换)
3. 所以排除Reader,选择InputStream
public void readImg(ImageView iv) { File file = new File("/sdcard/temp.jpg"); if (file.exists()) { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(file); byte[] img = new byte[(int) file.length()];// 根据文件长度创建字节数组 fileInputStream.read(img); // 将图片字节信息写入到字节数组 Bitmap bitmap = BitmapFactory.decodeByteArray(img,0,img.length); iv.setImageBitmap(bitmap); // 显示图片 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
2.保存图片到本地
1. 保存到本地说明数据流是从应用到设备,因此使用输出流,所以选择OutputStream或Writer
2. 由于操作的数据对象是图片,使用字节流的话效率较高(不用经由Unicode转换)
3. 所以排除Writer,选择OutputStream
public void saveImg() { InputStream inputStream = null; FileOutputStream fileOutputStream = null; try { URL url = new URL("https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/h%3D360/sign=e572f27e9058d109dbe3afb4e158ccd0/b7fd5266d0160924933e331bd60735fae6cd3492.jpg"); URLConnection urlConnect = url.openConnection(); urlConnect.setConnectTimeout(5000); inputStream = urlConnect.getInputStream(); File tempFile = new File("/sdcard/temp.jpg");// 保存到临时文件中 if(tempFile.isDirectory()){ tempFile.delete(); } if (!tempFile.exists()) { tempFile.createNewFile(); } fileOutputStream = new FileOutputStream(tempFile);// 创建输出流,参数tempFile为写入的目标 byte[] buffer = new byte[1024]; int length = -1; while ((length = inputStream.read(buffer)) != -1) { // 读取字节,先存储到缓存区 fileOutputStream.write(buffer, 0, length); // 从缓存区提取数据,可以提升效率 } inputStream.close(); fileOutputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
3.从本地读取纯文档
1. 由于是读取,说明数据流是从设备流到应用,因此使用输入流,所以选择InputStream或Reader
2. 操作的数据对象是纯文档,需要使用字符流(纯文档需要经由Unicode转码)
3. 所以排除InputStream,选择Reader
public String readWold() { try { FileReader fileReader = new FileReader("/sdcard/test.txt"); BufferedReader bufferedReader = new BufferedReader(fileReader); String line = null; StringBuilder builder = new StringBuilder(); while ((line = bufferedReader.readLine()) != null) { builder.append(line + "\n"); } bufferedReader.close(); return builder.toString(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }
4.写入到本地纯文档
1.写入说明数据流是从应用到设备,因此使用输出流,所以选择OutputStream或Writer
2. 操作的数据对象是纯文档,需要使用字符流(纯文档或字符串需要经由Unicode转码)
3. 所以排除OutputStream,选择Writer
public void saveWord() { try { File file = new File("/sdcard/test.txt"); if (file.isDirectory()){ file.delete(); } if (!file.exists()){ file.createNewFile(); } FileWriter fileWriter = new FileWriter(file); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write("Hi,I am Chaos!"); bufferedWriter.newLine(); bufferedWriter.write("I am come from China!"); bufferedWriter.newLine(); bufferedWriter.flush(); bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } }
参考资料
字节流和字符流 http://www.jianshu.com/p/4edb6b99204e
Java中的字节流、缓冲流 http://blog.csdn.net/sinat_34669892/article/details/52738643
java 下载网络上的图片并保存到本地目录 http://takeme.iteye.com/blog/1683380
IO结构图源于百度图片
- java输入与输出流
- Java输入与输出
- java输入与输出
- java 输入与输出
- JAVA输入与输出
- Java输入流与输出流
- java字符输入流与输出流
- JAVA---IO流的输入与输出
- 输入与输出,流!
- java 的输入与输出
- Java字符输入与输出
- Java中的输入与输出
- java.io 输入与输出
- Java中的输入与输出
- Java的输入与输出
- JAVA输入\输出流
- Java输入/输出流
- Java 输入/输出流
- 浏览器缓存机制——http缓存
- Java实现URL下载图片到本地
- jquery获取form提交的数据
- Docker Engine 插件模型和 k8s 插件模型区别
- Codeforces Round #397 F. Souvenirs(线段树,离线)
- java输入与输出流
- Activity的生命周期
- 电子系统动态范围的理解
- 小程序开发之网络请求
- Java类型系统
- SVN 本地目录被手动删除后,cleanup时提示删除的目录被locked.
- 基础练习 2n皇后问题 dfs
- Unity传递复杂Json数据
- android 读取WebView缓存及清理WebView缓存