Java的流体系十分庞大,我们来看看体系图:
这么庞大的体系里面,常用的就那么几个,我们把它们抽取出来,如下图:
一:字节流
1:字节输入流
字节输入流的抽象基类是InputStream,常用的子类是 FileInputStream和BufferedInputStream。
1)FileInputStream
文件字节输入流:一切文件在系统中都是以字节的形式保存的,无论你是文档文件、视频文件、音频文件...,需要读取这些文件都可以用FileInputStream去读取其保存在存储介质(磁盘等)上的字节序列。
FileInputStream在创建时通过把文件名作为构造参数连接到该文件的字节内容,建立起字节流传输通道。
然后通过 read()、read(byte[])、read(byte[],int begin,int len) 三种方法从字节流中读取 一个字节、一组字节。
2)BufferedInputStream
带缓冲的字节输入流:上面我们知道文件字节输入流的读取时,是直接同字节流中读取的。由于字节流是与硬件(存储介质)进行的读取,所以速度较慢。而CPU需要使用数据时通过read()、read(byte[])读取数据时就要受到硬件IO的慢速度限制。我们又知道,CPU与内存发生的读写速度比硬件IO快10倍不止,所以优化读写的思路就有了:在内存中建立缓存区,先把存储介质中的字节读取到缓存区中。CPU需要数据时直接从缓冲区读就行了,缓冲区要足够大,在被读完后又触发fill()函数自动从存储介质的文件字节内容中读取字节存储到缓冲区数组。
BufferedInputStream 内部有一个缓冲区,默认大小为8M,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源 (譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容返回给用户.由于从缓冲区里读取数据远比直接从存储介质读取速度快,所以BufferedInputStream的效率很高。
public class OutputStreamWriter extends Writer { // 流编码类,所有操作都交给它完成。 private final StreamEncoder se; // 创建使用指定字符的OutputStreamWriter。 public OutputStreamWriter(OutputStream out, String charsetName) throws UnsupportedEncodingException { super(out); if (charsetName == null) throw new NullPointerException("charsetName"); se = StreamEncoder.forOutputStreamWriter(out, this, charsetName); } // 创建使用默认字符的OutputStreamWriter。 public OutputStreamWriter(OutputStream out) { super(out); try { se = StreamEncoder.forOutputStreamWriter(out, this, (String)null); } catch (UnsupportedEncodingException e) { throw new Error(e); } } // 创建使用指定字符集的OutputStreamWriter。 public OutputStreamWriter(OutputStream out, Charset cs) { super(out); if (cs == null) throw new NullPointerException("charset"); se = StreamEncoder.forOutputStreamWriter(out, this, cs); } // 创建使用指定字符集编码器的OutputStreamWriter。 public OutputStreamWriter(OutputStream out, CharsetEncoder enc) { super(out); if (enc == null) throw new NullPointerException("charset encoder"); se = StreamEncoder.forOutputStreamWriter(out, this, enc); } // 返回该流使用的字符编码名。如果流已经关闭,则此方法可能返回 null。 public String getEncoding() { return se.getEncoding(); } // 刷新输出缓冲区到底层字节流,而不刷新字节流本身。该方法可以被PrintStream调用。 void flushBuffer() throws IOException { se.flushBuffer(); } // 写入单个字符 public void write(int c) throws IOException { se.write(c); } // 写入字符数组的一部分 public void write(char cbuf[], int off, int len) throws IOException { se.write(cbuf, off, len); } // 写入字符串的一部分 public void write(String str, int off, int len) throws IOException { se.write(str, off, len); } // 刷新该流。可以发现,刷新缓冲区其实是通过流编码类的flush()实现的,故可以看出,缓冲区是流编码类自带的而不是OutputStreamWriter实现的。 public void flush() throws IOException { se.flush(); } // 关闭该流。 public void close() throws IOException { se.close(); } }
每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积(传递给 write() 方法的字符没有缓冲,输出数组才有缓冲)。为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。
2)BufferedWriter
带缓冲的字符输出流:与OutputStreamWriter的缓冲不同,BufferedWriter的缓冲是真正由自己创建的缓冲数组来实现的。故此:不需要频繁调用编码转换器进行缓冲,而且,它可以提供单个字符、数组和字符串的缓冲(编码转换器只能缓冲字符数组和字符串)。
BufferedWriter可以在创建时把一个OutputStreamWriter进行包装,为输出流建立缓冲;
然后,通过
void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
void write(int c)
写入单个字符。
void write(String s, int off, int len)
写入字符串的某一部分。
向缓冲区写入数据。
还可以通过
void newLine()
写入一个行分隔符。
最后,可以手动控制缓冲区的数据刷新:
void flush() 刷新该流的缓冲。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
时间:2020-03-30
字节流和字符流 对于文件必然有读和写的操作,读和写就对应了输入和输出流,流又分成字节和字符流. 1.从对文件的操作来讲,有读和写的操作--也就是输入和输出. 2.从流的流向来讲,有输入和输出之分. 3.从流的内容来讲,有字节和字符之分. 这篇文章先后讲解IO流中的字节流和字符流的输入和输出操作. 一.字节流 1)输入和输出流 首先,字节流要进行读和写,也就是输入和输出,所以它有两个抽象的父类InputStream.OutputStream. InputStream抽象了应用程序读取数据的方式,即
本文实例为大家分享了文件字符流的使用方法,供大家参考,具体内容如下 案例1: 读取一个文件并写入到另一个文件中,char[] 来中转. 首先要在E盘下创建一个文本文档,命名为test.txt,输入一些字符串. public class Demo_5 { public static void main(String[] args) { FileReader fr=null; //文件取出字符流对象(输入流) FileWriter fw=null; //写入到文件(输出流) try { fr=new
此次案例将以复制文件的形式来演示IO字节流的基本操作,复制一个mp3文件,文件信息如下图: main方法测试 public static void main(String[] args) throws Exception { //源文件 String srcFile = "src/a.mp3"; //目的文件 String destFile = "src/b.mp3"; long start = System.currentTimeMillis(); ... 复制文
Java IO--字节流复制图片实例 字节流用来操作图片.视屏.音频(进制文件) 实例代码: package learn; import java.io.*; public class Learn{ public static void main(String[] args) throws IOException { File file1=new File("D:/a.jpg"); File file2=new File("D:/b.jpg"); byte[] b=
Java-IO流 字符流 java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码). 文件是byte byte byte ... 的数据序列. 文本文件是文本(char)序列按照某种编码方案(uft-8.utf-16be.gbk)序列化为byte的存储结果. 字符流(Reader.Writer)-->操作的是文本.文本文件 1.字符的处理,一次处理一个字符 2.字符的底层仍然是基本的字节序列 3.字符流的基本实现: InputStreamReader是字节流通向字符
案例1: 演示FileInputStream类的使用(用FileInputStream的对象把文件读入到内存) 首先要在E盘新建一个文本文件,命名为test.txt,输入若干字符 public class Demo_2 { public static void main(String[] args) { File f=new File("e://test.txt"); //得到一个文件对象f,指向e://test.txt FileInputStream fis=null; try {
字符流: 1.加入字符缓存流,增强读取功能(readLine) 2.更高效的读取数据 BufferedReader 从字符输入流读取文本,缓冲各个字符,从而实现字符.数组和行的高效读取. FileReader:内部使用InputStreamReader,解码过程,byte->char,默认缓存大小为8k BufferReader:默认缓存大小为8k,但可以手动指定缓存大小,把数据读取到缓存中,减少每次转换过程,效率更高 /字符输入缓冲流 private static void charReade
java从控制台接收一个数字的实例详解 功能: 从控制台接收一个数 实现代码: import java.io.*; //引入一个IO流的包 public class helloworld1 { public static void main(String args[]) { try{ //输入流,从键盘接收数 InputStreamReader isr=new InputStreamReader(System.in); BufferedReader br=new BufferedReader(i
Java对象深复制与浅复制实例详解 我们在遇到一些业务场景的时候经常需要对对象进行复制,对于对象的复制一般有两种方式,深复制和浅复制 浅复制:对象的复制仅是对象本身,对象引用的其它对方并不会复制. 深复制:对象的复制包含对象引用的对象. Java所有对象的基类提供了clone方法,但是这个方法是protected native修饰,因此只暴露给之类去重写,外部是无法直接调用的. 我们现在来测试两种复制,首选是浅复制,浅复制要实现Cloneable接口. // 课程对象 class Class
java 中Excel转shape file的实例详解 概述: 本文讲述如何结合geotools和POI实现Excel到shp的转换,再结合前文shp到geojson数据的转换,即可实现用户上传excel数据并在web端的展示功能. 截图: 原始Excel文件 运行耗时 运行结果 代码: package com.lzugis.geotools; import com.lzugis.CommonMethod; import com.vividsolutions.jts.geom.Coordina
Java 重载.重写.构造函数的实例详解 方法重写 1.重写只能出现在继承关系之中.当一个类继承它的父类方法时,都有机会重写该父类的方法.一个特例是父类的方法被标识为final.重写的主要优点是能够定义某个子类型特有的行为. class Animal { public void eat(){ System.out.println ("Animal is eating."); } } class Horse extends Animal{ public void eat(){ Syste
一 概述 1.什么是动态查询? 从多个查询条件中随机选择若干个组合成一个DQL语句进行查询,这一过程叫做动态查询. 2.动态查询的难点 可供选择的查询条件多,组合情况多,难以一一列举. 3.最终查询语句的构成 一旦用户向查询条件中输入数据,该查询条件就成为最终条件的一部分. 二 基本原理 1.SQL基本框架 无论查询条件如何,查询字段与数据库是固定不变的,这些固定不变的内容构成SQL语句的基本框架,如 select column... from table. 2.StringBuilder形成D
java 中 String format 和Math类实例详解 java字符串格式化输出 @Test public void test() { // TODO Auto-generated method stub //可用printf(); System.out.println(String.format("I am %s", "jj")); //%s字符串 System.out.println(String.format("首字母是 %c",
在上篇文章给大家介绍了FastDFS安装和配置整合Nginx-1.13.3的方法,大家可以点击查看下. 今天使用Java代码实现文件的上传和下载.对此作者提供了Java API支持,下载fastdfs-client-java将源码添加到项目中.或者在Maven项目pom.xml文件中添加依赖 <dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</arti
java 数据结构中栈和队列的实例详解 栈和队列是两种重要的线性数据结构,都是在一个特定的范围的存储单元中的存储数据.与线性表相比,它们的插入和删除操作收到更多的约束和限定,又被称为限定性的线性表结构.栈是先进后出FILO,队列是先进先出FIFO,但是有的数据结构按照一定的条件排队数据的队列,这时候的队列属于特殊队列,不一定按照上面的原则. 实现栈:采用数组和链表两种方法来实现栈 链表方法: package com.cl.content01; /* * 使用链表来实现栈 */ public cl
Java使用AES加密和解密的实例详解 前言: AES的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128.192.256,分组长度128位,算法应易于各种硬件和软件实现.1998年NIST开始AES第一轮分析.测试和征集,共产生了15个候选算法.1999年3月完成了第二轮AES2的分析.测试.2000年10月2日美国政府正式宣布选中比利时密码学家Joan Daemen 和 Vincent Rijmen 提出的一种密码算法RIJNDAEL 作为 AES. 在应用方面,尽管DES在安全上
动态统计当前输入内容的字节.字符数的实例详解 看到网上有好多利用charAt方法,原理也很简单,用正则判断是不是中文,如果是的话,字节数就加2,不是的话,字节数就加1. 后来发现另一种方式,由于一个汉字对应是两个字节,可利用正则,将匹配到的汉字用两个字符代替,例如:"xx",最后获得转化后的字符串的长度即是字节数. 而字符数就是对应有多少个汉字.字母.符号. //短信内容字数 $scope.bytesCount= 0; $scope.smsLength = 0; $scope.smsC