- 浏览: 324406 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (254)
- java (178)
- tomcat (6)
- 邮件 (1)
- smtp (1)
- Linux (2)
- 编码 (2)
- 导入工程 (1)
- Specification Level (1)
- hibernate (10)
- 字段类型 (1)
- 字段类型匹配 (1)
- 数据库 (3)
- sql (9)
- struts2 (8)
- 类型转换 (2)
- java,MyEclipse,SVN (1)
- Myecplise (4)
- 输入校验 (1)
- JFrame (2)
- Oracle (8)
- google (1)
- Swing (3)
- Fusioncharts (1)
- 找工作 (0)
- js (4)
- jsp (11)
- displaytag (1)
- spring (8)
- 工作 (1)
- String (1)
- 算法 (2)
- IO (1)
- xml (3)
- 设计模式 (1)
- UML (1)
- 文档 (1)
- ajax (1)
- 日常 (7)
- sql server (1)
- mysql (3)
- git (1)
- Maven (1)
- mongodb (1)
- postman (1)
最新评论
首先讲到的是File类,首先查看博客文章“Java IO File类总结”
流类:
流的概念:
---java程序通过流来完成输入/输出。流是生产或消费信息的抽象。流通过Java的输入/输出系统与物理设备链接。尽管与他们链接的物理设备不尽相同,所有流的行为具有同样的方式。这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到控制台,磁盘文件或相连的网络。流是处理输入/输出的一个洁净的方法,例如它不需要代码理解键盘和网络的不同。Java中流的实现是在java.io包定义的类层次结构内部的。
输入/输出流的概念:
---输入/输出时,数据在通信通道中流动。所谓“数据流(stream)”指的是所有数据通信通道之中,数据的起点和终点。信息的通道就是一个数据流。只要是数据从一个地方“流”到另一个地方,这种数据流动的通道都可以称为数据流。
---输入/输出是相对于程序来说的。程序在使用数据时所扮演的角色有两个:一个是源,一个是目的。若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个“输出数据流”(数据从程序流出)。若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流”(数据从程序外流向程序)
输入/输出类:
---在java.io包中提供了60多个类(流)。
---从功能上分为两大类:输入流和输出流。
---从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。
---字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer。
字符流底层也是采用字节流实现的。在底层,所有的输入/输出都是字节形式的。基于字符的流只处理字符提供方便有效的方法。
Java 2定义了两种类型的流:字节流和字符流。字节流(byte stream)为处理字节的输入和输出提供了方便的方法。例如使用字节流可以读取或写入二进制数据。字符流(character stream)为字符的输入和输出提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效。
---字节流类(Byte Streams) 字节流类用于向字节流读写8位二进制的字节。一般的,字节流类主要用于读写诸如图像或声音等的二进制数据。
---字符流类(Character Streams) 字符流类用于向字符流读写16位二进制字符。
两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。
输入流:
读数据的逻辑为:
open a stream【打开一个流,就像一个水库,开砸了才能取水】
while more information【一次不可能把全部信息读取完,读一部分之后while判断是否还有更多信息】
read information【还有更多信息的话就继续读取信息】
close the stream【读取完信息之后关闭流,流是一种资源,必须关闭了其他地方才能再使用,比如我打开一个文件,但是没有关,那么我就删不掉这个文件,一样的道理】
写数据的逻辑为:
open a stream
while more information
write information
close the stream
流的下一个分类(节点流和过滤流):
节点流直接是和目标交互的,比如说我要从硬盘上读取一个文件,那么这个节点流就是针对于文件的流,直接和文件进行连接的,在读取的过程当中,我可以对节点刘进行一个过滤(比如读取到信息之后我可以对它进行一个包装,增加一些新的功能等),这就是过滤流。过滤流总是与节点流打交道或是与其他的过滤流打交道,而节点刘总是与特定的目标信息打交道的。
字节流类以InputStream和OutputStream为顶层类,他们都是抽象类(abstract)
抽象类InputStream和OutputStream定义了实现其他流类的关键方法。最重要的两种方法是read()和write(),他们分别对数据的字节进行读写。两种方法都在InputStream和OutputStream中被定义为抽象方法。它们被派生的流类重写。
每个抽象类都有多个具体的子类,这些子类对不同的外设进行处理,例如磁盘文件,网络连接,甚至是内存缓冲区。
InputStream三个基本的读方法:
---abstract int read():读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
---int read(byte[] b):将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
---int read(byte[] b, int off, int len):将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。Off指定在数组b中存放数据的其实偏移位置;len指定读取的最大字节数。
问题:为什么只有第一个read方法是抽象的,而其余两个read方法都是具体的?
答案:因为第二个read方法依靠第三个read方法来实现,而第三个read方法又依靠第一个read方法来实现,所以说只有第一个read方法是与具体的I/O设备相关的,它需要InputStream的子类来实现。
Jdk提供的InputStream的每一个子类里面都要重写read()这个方法,而用于完成不同功能的输入流子类,他们重写read()方法的实现方式肯定是不同的。这个read()方法你即便在InputStream你给我定义好了,我的子类里面也一定需要把它重写,你定义的肯定是不符合要求的,这不就符合抽象类的它的含义么(包含抽象方法,包含具体方法,它的子类必须实现抽象方法),具体read()的实现方式你根据自己的实际需求来定,假如你是处理网络的,你就按照网络的那种方式来实现,假如你是处理字节数组的,你就按照字节数组的那种方式来实现,你处理文件的,就按照文件的方式来实现…..。所以InputStream不同的子类对read()方法的实现完全是不一样的。
下面实际开发中流的使用最最常见的一种用法(固定模式):
InputStream的子类以及节点流、过滤流的一些讲解:
FilterInputStream是一个过滤流,FilterInputStream 包含其他一些输入流(节点流),它将这些流用作其基本数据源,我们通常使用它的子类(4个子类)。它的一些子类都是过滤流,这些过滤流可以包装其他的节点流。你用一个过滤流包装了一个节点流,那么这个节点流就相应的增加了新的功能。例如用BufferedInputStream包装FileInputStream,那么这个FileInputStream就具有了缓冲的功能。注:上面图里面的InputStream的直接子类里面除了FilterInputStream是过滤流外,其余所有类都是节点流。
InputStream中包含一套字节输入流需要的方法,可以完成最基本的从输入流读入数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的InputStream子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输入方法来实现对外设的输入操作。
InputStream类子类对象自然也继承了InputStream类的方法。常用的方法有:读数据的方法read(),获取输入流字节数的方法available(),定位输入位置指针的方法skip()、reset()、mark()等。
下面讲解OutputStream:
---三个基本的写方法:
abstract void write(int b):往输出流中写入一个字节。
void write(byte[] b):往输出流中写入数组b中的所有字节。
void write(byte[] b, int off, int len):往输出流中写入数组b中从偏移量off开始的len个字节的数据。
---其他方法:
void flush():刷新输出流,强制缓冲区中的输出字节被写出。
void close():关闭输出流,释放和这个流相关的系统资源。
OutputStream是定义了流式字节输出模式的抽象类。该类的所有方法返回一个void值并且在出错情况下引发一个IOException异常。
通过打开一个到目标的输出流,程序可以向外部目标顺序写数据。
OutputStream的子类以及节点流、过滤流的一些讲解:
和输入流一样,输出流OutputStream的子类里面也同样有一个过滤流(其他的都是节点流),这个流的三个子类都是过滤流,可以包装其他的节点流。注:上面图里面的OutputStream的直接子类里面除了FilterOutputStream是过滤流外,其余所有类都是节点流。
下面重点讲解过滤流:
在InputStream类和OutputStream类子类中,过滤流FilterInputStream和FilterOutputStream过滤流抽象类又派生出DataInputStream和DataOutputStream数据输入输出流类等子类,这些类都作为过滤流类来使用。
过滤流的主要特点是在输入输出数据的同时能对所传输的数据做指定类型或格式的转换,即可实现对二进制字节数据的理解和编码转换。
数据输出流DataInputStream中定义了多个针对不同类型数据的读方法,如readByte()、readBoolean()、readShort()、readChar()、reading()、readLong()、readFloat()、readDouble()、readLine()等。
数据输出流DataOutputStream中定义了多个针对不同类型数据的写方法,如writeByte()、writeBoolean()、writeShort()、writeChar()、writeInt()、writeLong()、writeFloat()、writeDouble()、writeChars()等。
过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。
类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类。
===========================过滤流讲解完毕====================================
OutputStream中包含一套字节输出流需要的方法,可以完成最基本的输出数据到输出流的功能。当Java程序需要将数据输出到外设时,可根据数据的不同形式,创建一个适当的OutputStream子类类型的对象来完成与外设的连接,然后再调用执行这个流类对象的特定输出方法来实现对相应外设的输出操作。
OutputStream类子类对象也继承了OutputStream类的方法。常用的方法有:写数据的方法write(),关闭流方法close()等。
下面是OutputStream一个测试类:
基本流类讲解:
FileInputStream和FileOutputStream:节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件(可以用第二个参数指定不覆盖,追加内容)。
BufferedInputStream和BufferedOutputStream:过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。
DataInputStream和DataOutputStream:过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。
PipedInputStream和PipedOutputStream:管道流(节点流),用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。
I/O流的链接:
BufferedOutputStream(缓冲输出流):
缓冲输出流BufferedOutputStream类提供和FileOutputStream类同样的写操作方法,但所有输出全部写入缓冲区中。当写满缓冲区或关闭输出流时,它再一次性输出到流,或者用flush()方法主动将缓冲区输出到流。
BufferedOutputStream与任何一个OutputStream相同,除了用一个另外的flush()方法来保证数据缓冲区被写入到实际的输出设备。
BufferedOutputStream通过减小系统写数据的时间而提高性能。
如果不使用缓冲输出流,直接使用FileOutputStream,那么就是往流里面写一个字符,然后就直接往文件里面写一次,操作一次文件,对文件的操作相当频繁。
缓冲去里面的内容写到文件里面有两种方式:
1、调用BufferedOutputStream的flush()方法。
2、调用close()方法之前会把缓冲区里的东西都写入流里面。
下面是BufferedOutputStream一个测试类:
不像缓冲输入,缓冲输出不提供额外的功能,Java中输出缓冲区是为了提高性能的。下面是两个可用的构造方法:
---BufferedOutputStream(OutputStream outputStream)
---BufferedOutputStream(OutputStream outputStream, int bufSize)
---第一种形式创建了一个使用512字节缓冲区的缓冲流。
---第二种形式,缓冲区的大小用bufSize参数传入。
要想在程序结束之前将缓冲区里的数据写入磁盘,除了填满缓冲区或关闭输出流外,还可以显示调用flush()方法。Flush()方法的声明为:
---public void flush() throws IOException
BufferedInputStream(缓冲输入流):
---public void mark(int readlimit):在此输入流中标记当前的位置。对reset方法的后续调用会在最后标记的位置重新定位此流,以便后续读取重新读取相同的字节。
---public void reset():将此流重新定位到对此输入流最后调用mark方法时的位置。
缓冲一个输入流同样提供了在可用缓冲区的流内支持向后移动的必备基础。除了在任何InputStream类中执行的read()和skip()方法外,BufferedInputStream同样支持mark()和reset()方法。
BufferedInputStream.markSupported()返回true是这一支持的体现。
当创建缓冲输入流BufferedInputStream时,一个输入缓冲区数组被创建,来自流的数据填入缓冲去,一次课填入许多字节。
缓冲输入/输出是一个非常普通的性能优化。Java的BufferedInputStream类允许把任何InputStream类“包装”成缓冲流并使它的性能提高。
BufferedInputStream有两个构造方法:
---BufferedInputStream(InputStream inputStream)
---BufferedInputStream(InputStream inputStream, int bufSize)
---第一种形式创建BufferedInputStream流对象并为以后的使用保存InputStream参数in,并创建一个内部缓冲区数组来保存输入数据。
---第二种形式用指定的缓冲区大小size创建BufferedInputStrean流对象,并为以后的使用保存InputStream参数in。
缓冲字节流:
若处理的数据量较多,为避免每个字节的读写都对流进行,可以使用过滤流类的子类缓冲流。缓冲流建立一个内部缓冲区,输入输出数据先读写到缓冲区中进行操作,这样可以提高文件流的操作效率。
下面是ByteArrayInputStream和ByteArrayOutputStream两个使用示例:
关于io的笔记太多,决定最后还是把笔记里面的两个pdf文档上传到博客文章的附件作为日后查看笔记的地址(IO_1.pdf和IO_2.pdf,老师讲课时候的课件)。上面记录的只作为一个样例查看(比如笔记顺序,模块汇总等等,上面记录的笔记都是比较重要的,并且所有笔记在附件的pdf文档里面都有)。
下面是DataInputStream和DataOutputStream的使用示例:
实际项目里面一定会用到的流类有:FileInputStream、FileOutputStream、BufferedInputStream、BufferedOutputStream、ByteArrayInputStream、ByteArrayOutputStream。其他的虽然用,但是用的不多,有的甚至用的很少。
下面开始讲解java io的另一个重要模块:字符流,(上面讲解的都是字节流)。
首先查看字符流的相关pdf文档IO_3.pdf,了解详细知识。并且听完之后把pdf文档里面的笔记重写在这个文档里面记录一遍并且贴到将来的博客文章里面。
尽管字节流提供了处理任何类型输入/输出操作的足够的功能,它们不能直接操作Unicode字符。既然Java的一个主要目的是支持“只写一次,到处运行”的哲学,包括直接的字符输入/输出支持是必要的。本节将讨论几个字符输入/输出类。字符流层次结构的顶层是Reader 和Writer 抽象类。我们将从它们开始。
字符输入/输出类是在java 的1.1版本中新加的。由此,你仍然可以发现遗留下的程序代码在应该使用字符流时却使用了字节流。当遇到这种代码,最好更新它
由于Java采用16位的Unicode字符,因此需要基于字符的输入/输出操作。从Java1.1版开始,加入了专门处理字符流的抽象类Reader和Writer,前者用于处理输入,后者用于处理输出。这两个类类似于InputStream和OuputStream,也只是提供一些用于字符流的规定,本身不能用来生成对象。
Reader和Writer类也有较多的子类,与字节流类似,它们用来创建具体的字符流对象进行I/O操作。字符流的读写等方法与字节流的相应方法都很类似,但读写对象使用的是字符
Reader中包含一套字符输入流需要的方法,可以完成最基本的从输入流读入数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的Reader子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输入方法,如read(),来实现对相应外设的输入操作。
Writer中包含一套字符输出流需要的方法,可以完成最基本的输出数据到输出流的功能。当Java程序需要将数据输出到外设时,可根据数据的不同形式,也要创建一个适当的Writer子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输出方法,如write(),来实现对相应外设的输出操作。
• Reader是定义Java的流式字符输入模式的抽象类。该类的所有方法在出错情况下都将引发IOException 异常 。
• Writer 是定义流式字符输出的抽象类。所有该类的方法都返回一个void 值并在出错条件下引发IOException 异常。
Java.io包中Reader的类层次:
像里面的FilterReader也是过滤类型的,和字节流里面的过滤流使用方式类似。
Java.io包中Writer的类层次:
像里面的FilterWriter也是过滤类型的,和字节流里面的过滤流使用方式类似。
Java 程序语言使用Unicode来表示字符串和字符,Unicode使用两个字节来表示一个字符,即一个字符占16位(一个字节占8位)。
InputStreamReader和OutputStreamWriter两个类是java.io包中用于处理字符流的基本类,用来在字节流和字符流之间搭一座“桥”。这里字节流的编码规范与具体的平台有关,可以在构造流对象时指定规范,也可以使用当前平台的缺省规范。
• InputStreamReader和OutputStreamWriter类的主要构造方法如下
–public InputSteamReader(InputSteam in)
–public InputSteamReader(InputSteam in,String enc)
–public OutputStreamWriter(OutputStream out)
–public OutputStreamWriter(OutputStream out,String enc)
• 其中in和out分别为输入和输出字节流对象,enc为指定的编码规范(若无此参数,表示
使用当前平台的缺省规范,可用getEncoding()方法得到当前字符流所用的编码方式)。
• 读写字符的方法read()、write(),关闭流的方法close()等与Reader和Writer类的同名方法用法都是类似的。
• FileReader类创建了一个可以读取文件内容的Reader类。FileReader继承于InputStreamReader。它最常用的构造方法显示如下
–FileReader(String filePath)
–FileReader(File fileObj)
–每一个都能引发一个FileNotFoundException异常。这里,filePath是一个文件的完整路径,fileObj是描述该文件的File 对象。
• FileWriter 创建一个可以写文件的Writer 类。 FileWriter继承于OutputStreamWriter.它最常用的构造方法如下:
–FileWriter(String filePath)
–FileWriter(String filePath, boolean append)
–FileWriter(File fileObj)
–append :如果为 true,则将字节写入文件末尾处,而不是写入文件开始处
• FileWriter类的创建不依赖于文件存在与否。在创建文件之前,FileWriter将在创建对象时打开它来作为输出。如果你试图打开一个只读文件,将引发一个IOException异常。
• CharArrayReader 是一个把字符数组作为源的输入流的实现。该类有两个构造方法,每一个都需要一个字符数组提供数据源
–CharArrayReader(char array[ ])
–CharArrayReader(char array[ ], int start, int numChars)
–这里,array是输入源。第二个构造方法从你的字符数组的子集创建了一个Reader,该子集以start指定的索引开始,长度为numChars。
• BufferedReader 通过缓冲输入提高性能。它有两个构造方法
–BufferedReader(Reader inputStream)
–BufferedReader(Reader inputStream, int bufSize)
–第一种形式创建一个默认缓冲区长度的缓冲字符流。第二种形式,缓冲区长度由bufSize传入
• 和字节流的情况相同,缓冲一个输入字符流同样提供支持可用缓冲区中流内反向移动的基础。为支持这点,BufferedReader 实现了mark( )和reset( )方法,并且BufferedReader.markSupported( ) 返回true
• BufferedWriter是一个增加了flush( )方法的Writer。flush( )方法可以用来确保数据缓冲区确实被写到实际的输出流。用BufferedWriter 可以通过减小数据被实际的写到输出流的次数而提高程序的性能。
• BufferedWriter有两个构造方法:
–BufferedWriter(Writer outputStream)
–BufferedWriter(Writer outputStream, int bufSize)
–第一种形式创建了使用默认大小缓冲区的缓冲流。第二种形式中,缓冲区大小是由bufSize参数传入的
• ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基于常用的英文字符的一套电脑编码系统。我们知道英文中经常使用的字符、数字符号被计算机处理时都是以二进制码的形式出现的。这种二进制码的集合就是所谓的ASCII码。每一个ASCII码与一个8位(bit)二进制数对应。其最高位是0,相应的十进制数是0-127。如,数字“0”的编码用十进制数表示就是48。另有128个扩展的ASCII码,最高位都是1,由一些制表符和其它符号组成。ASCII是现今最通用的单字节编码系统。
• GB2312:GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集-基本集》。主要用于给每一个中文字符指定相应的数字,也就是进行编码。一个中文字符用两个字节的数字来表示,为了和ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。【用来表示中文的编码格式】
• GBK:为了对更多的字符进行编码,国家又发布了新的编码系统GBK(GBK的K是“扩展”的汉语拼音第一个字母)。在新的编码系统里,除了完全兼容GB2312 外,还对繁体中文、一些不常用的汉字和许多符号进行了编码。 【它是能表示一些生僻的GB2312表示不了的中文】
• ISO-8859-1:是西方国家所使用的字符编码集,是一种单字节的字符集 ,而英文实际上只用了其中数字小于128的部分。【不能表示中文】
• Unicode:这是一种通用的字符集,对所有语言的文字进行了统一编码,对每一个字符都用2个字节来表示,对于英文字符采取前面加“0”字节的策略实现等长兼容。如 “a” 的ASCII码为0x61,UNICODE就为0x00,0x61。(在internet上传输效率较低)
• UTF-8:Eight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,UCS 是所有其他字符集标准的一个超集)。一个7位的ASCII码值,对应的UTF码是一个字节。如果字符是0x0000,或在0x0080与0x007f之间,对应的UTF码是两个字节,如果字符在0x0800与0xffff之间,对应的UTF码是三个字节(汉字为3个字节)。【最通用的一种编码格式,所有的语言都能表示,国际化里面一般都用的这种编码格式】
下面来个小的总结:
• InputStream和OutputStream:字节流的输入输出。
• Reader和Writer:字符流的输入输出。
• 流的链接(Java I/O库的设计原则)
下面是字符流的一些使用示例(重点查看):
RandomAccessFile类比较特殊,即能读,又能写。而且没有继承InputStream和OutputStream。这个类了解下就可以。
把IO_1.pdf和IO_2.pdf上传附件即可,IO_3.pdf和Decorator.pdf已经在笔记里面总结完了。
附件里面的IO_2.zip里面装IO_2.pdf,IO_1.zip里面装IO_1.pdf
流类:
流的概念:
---java程序通过流来完成输入/输出。流是生产或消费信息的抽象。流通过Java的输入/输出系统与物理设备链接。尽管与他们链接的物理设备不尽相同,所有流的行为具有同样的方式。这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到控制台,磁盘文件或相连的网络。流是处理输入/输出的一个洁净的方法,例如它不需要代码理解键盘和网络的不同。Java中流的实现是在java.io包定义的类层次结构内部的。
输入/输出流的概念:
---输入/输出时,数据在通信通道中流动。所谓“数据流(stream)”指的是所有数据通信通道之中,数据的起点和终点。信息的通道就是一个数据流。只要是数据从一个地方“流”到另一个地方,这种数据流动的通道都可以称为数据流。
---输入/输出是相对于程序来说的。程序在使用数据时所扮演的角色有两个:一个是源,一个是目的。若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个“输出数据流”(数据从程序流出)。若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流”(数据从程序外流向程序)
输入/输出类:
---在java.io包中提供了60多个类(流)。
---从功能上分为两大类:输入流和输出流。
---从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。
---字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer。
字符流底层也是采用字节流实现的。在底层,所有的输入/输出都是字节形式的。基于字符的流只处理字符提供方便有效的方法。
Java 2定义了两种类型的流:字节流和字符流。字节流(byte stream)为处理字节的输入和输出提供了方便的方法。例如使用字节流可以读取或写入二进制数据。字符流(character stream)为字符的输入和输出提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效。
---字节流类(Byte Streams) 字节流类用于向字节流读写8位二进制的字节。一般的,字节流类主要用于读写诸如图像或声音等的二进制数据。
---字符流类(Character Streams) 字符流类用于向字符流读写16位二进制字符。
两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。
输入流:
读数据的逻辑为:
open a stream【打开一个流,就像一个水库,开砸了才能取水】
while more information【一次不可能把全部信息读取完,读一部分之后while判断是否还有更多信息】
read information【还有更多信息的话就继续读取信息】
close the stream【读取完信息之后关闭流,流是一种资源,必须关闭了其他地方才能再使用,比如我打开一个文件,但是没有关,那么我就删不掉这个文件,一样的道理】
写数据的逻辑为:
open a stream
while more information
write information
close the stream
流的下一个分类(节点流和过滤流):
节点流直接是和目标交互的,比如说我要从硬盘上读取一个文件,那么这个节点流就是针对于文件的流,直接和文件进行连接的,在读取的过程当中,我可以对节点刘进行一个过滤(比如读取到信息之后我可以对它进行一个包装,增加一些新的功能等),这就是过滤流。过滤流总是与节点流打交道或是与其他的过滤流打交道,而节点刘总是与特定的目标信息打交道的。
字节流类以InputStream和OutputStream为顶层类,他们都是抽象类(abstract)
抽象类InputStream和OutputStream定义了实现其他流类的关键方法。最重要的两种方法是read()和write(),他们分别对数据的字节进行读写。两种方法都在InputStream和OutputStream中被定义为抽象方法。它们被派生的流类重写。
每个抽象类都有多个具体的子类,这些子类对不同的外设进行处理,例如磁盘文件,网络连接,甚至是内存缓冲区。
InputStream三个基本的读方法:
---abstract int read():读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
---int read(byte[] b):将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
---int read(byte[] b, int off, int len):将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。Off指定在数组b中存放数据的其实偏移位置;len指定读取的最大字节数。
问题:为什么只有第一个read方法是抽象的,而其余两个read方法都是具体的?
答案:因为第二个read方法依靠第三个read方法来实现,而第三个read方法又依靠第一个read方法来实现,所以说只有第一个read方法是与具体的I/O设备相关的,它需要InputStream的子类来实现。
Jdk提供的InputStream的每一个子类里面都要重写read()这个方法,而用于完成不同功能的输入流子类,他们重写read()方法的实现方式肯定是不同的。这个read()方法你即便在InputStream你给我定义好了,我的子类里面也一定需要把它重写,你定义的肯定是不符合要求的,这不就符合抽象类的它的含义么(包含抽象方法,包含具体方法,它的子类必须实现抽象方法),具体read()的实现方式你根据自己的实际需求来定,假如你是处理网络的,你就按照网络的那种方式来实现,假如你是处理字节数组的,你就按照字节数组的那种方式来实现,你处理文件的,就按照文件的方式来实现…..。所以InputStream不同的子类对read()方法的实现完全是不一样的。
下面实际开发中流的使用最最常见的一种用法(固定模式):
package com.shengshiyuan.io2; import java.io.File; import java.io.FileInputStream; /** * 输入流使用的常见的通用使用方式 * 类: InputStreamTest1 <br> * 描述: TODO <br> * 作者: * 时间: Nov 13, 2013 3:23:44 PM */ public class InputStreamTest1 { public static void main(String[] args) throws Exception { FileInputStream inputStream = new FileInputStream(new File( "C:/a/hello.txt")); byte[] b = new byte[200]; StringBuffer str = new StringBuffer(); int length = 0; // 从0开始读,最多读200个,并返回实际读取到的字节个数赋给length while ((length = inputStream.read(b, 0, 200)) != -1) { // 把字节数组转换成字符串,从第0个位置开始转,并指定将length个字节转换成字符。绝对不能写200哈,因为最后一次读取到的字节数很可能不够200个 String s = new String(b, 0, length); str.append(s); } System.out.println(str.toString()); inputStream.close(); } }
InputStream的子类以及节点流、过滤流的一些讲解:
FilterInputStream是一个过滤流,FilterInputStream 包含其他一些输入流(节点流),它将这些流用作其基本数据源,我们通常使用它的子类(4个子类)。它的一些子类都是过滤流,这些过滤流可以包装其他的节点流。你用一个过滤流包装了一个节点流,那么这个节点流就相应的增加了新的功能。例如用BufferedInputStream包装FileInputStream,那么这个FileInputStream就具有了缓冲的功能。注:上面图里面的InputStream的直接子类里面除了FilterInputStream是过滤流外,其余所有类都是节点流。
InputStream中包含一套字节输入流需要的方法,可以完成最基本的从输入流读入数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的InputStream子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输入方法来实现对外设的输入操作。
InputStream类子类对象自然也继承了InputStream类的方法。常用的方法有:读数据的方法read(),获取输入流字节数的方法available(),定位输入位置指针的方法skip()、reset()、mark()等。
下面讲解OutputStream:
---三个基本的写方法:
abstract void write(int b):往输出流中写入一个字节。
void write(byte[] b):往输出流中写入数组b中的所有字节。
void write(byte[] b, int off, int len):往输出流中写入数组b中从偏移量off开始的len个字节的数据。
---其他方法:
void flush():刷新输出流,强制缓冲区中的输出字节被写出。
void close():关闭输出流,释放和这个流相关的系统资源。
OutputStream是定义了流式字节输出模式的抽象类。该类的所有方法返回一个void值并且在出错情况下引发一个IOException异常。
通过打开一个到目标的输出流,程序可以向外部目标顺序写数据。
OutputStream的子类以及节点流、过滤流的一些讲解:
和输入流一样,输出流OutputStream的子类里面也同样有一个过滤流(其他的都是节点流),这个流的三个子类都是过滤流,可以包装其他的节点流。注:上面图里面的OutputStream的直接子类里面除了FilterOutputStream是过滤流外,其余所有类都是节点流。
下面重点讲解过滤流:
在InputStream类和OutputStream类子类中,过滤流FilterInputStream和FilterOutputStream过滤流抽象类又派生出DataInputStream和DataOutputStream数据输入输出流类等子类,这些类都作为过滤流类来使用。
过滤流的主要特点是在输入输出数据的同时能对所传输的数据做指定类型或格式的转换,即可实现对二进制字节数据的理解和编码转换。
数据输出流DataInputStream中定义了多个针对不同类型数据的读方法,如readByte()、readBoolean()、readShort()、readChar()、reading()、readLong()、readFloat()、readDouble()、readLine()等。
数据输出流DataOutputStream中定义了多个针对不同类型数据的写方法,如writeByte()、writeBoolean()、writeShort()、writeChar()、writeInt()、writeLong()、writeFloat()、writeDouble()、writeChars()等。
过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。
类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类。
===========================过滤流讲解完毕====================================
OutputStream中包含一套字节输出流需要的方法,可以完成最基本的输出数据到输出流的功能。当Java程序需要将数据输出到外设时,可根据数据的不同形式,创建一个适当的OutputStream子类类型的对象来完成与外设的连接,然后再调用执行这个流类对象的特定输出方法来实现对相应外设的输出操作。
OutputStream类子类对象也继承了OutputStream类的方法。常用的方法有:写数据的方法write(),关闭流方法close()等。
下面是OutputStream一个测试类:
package com.shengshiyuan.io2; import java.io.FileOutputStream; import java.io.OutputStream; /** * 文件输出流示例 * 类: OutputStreamTest1 <br> * 描述: TODO <br> * 作者: * 时间: Nov 14, 2013 11:12:17 AM */ public class OutputStreamTest1 { public static void main(String[] args) throws Exception { // 第二个参数如果为true,则将字节追加到文件末尾处;如果为false,则用现在的字节覆盖文件里面原来的内容 OutputStream os = new FileOutputStream("C:/a/hello.txt", true); String str = "123"; // 获得字符串的字节数组 byte[] buffer = str.getBytes(); // 写内容 os.write(buffer); os.close(); } }
基本流类讲解:
FileInputStream和FileOutputStream:节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件(可以用第二个参数指定不覆盖,追加内容)。
BufferedInputStream和BufferedOutputStream:过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。
DataInputStream和DataOutputStream:过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。
PipedInputStream和PipedOutputStream:管道流(节点流),用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。
I/O流的链接:
BufferedOutputStream(缓冲输出流):
缓冲输出流BufferedOutputStream类提供和FileOutputStream类同样的写操作方法,但所有输出全部写入缓冲区中。当写满缓冲区或关闭输出流时,它再一次性输出到流,或者用flush()方法主动将缓冲区输出到流。
BufferedOutputStream与任何一个OutputStream相同,除了用一个另外的flush()方法来保证数据缓冲区被写入到实际的输出设备。
BufferedOutputStream通过减小系统写数据的时间而提高性能。
如果不使用缓冲输出流,直接使用FileOutputStream,那么就是往流里面写一个字符,然后就直接往文件里面写一次,操作一次文件,对文件的操作相当频繁。
缓冲去里面的内容写到文件里面有两种方式:
1、调用BufferedOutputStream的flush()方法。
2、调用close()方法之前会把缓冲区里的东西都写入流里面。
下面是BufferedOutputStream一个测试类:
package com.shengshiyuan.io2; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.OutputStream; public class BufferedOutputStreamTest1 { public static void main(String[] args) throws Exception { OutputStream os = new FileOutputStream("1.txt"); BufferedOutputStream bos = new BufferedOutputStream(os); bos.write("http://www.google.com".getBytes()); bos.close(); os.close(); } }
不像缓冲输入,缓冲输出不提供额外的功能,Java中输出缓冲区是为了提高性能的。下面是两个可用的构造方法:
---BufferedOutputStream(OutputStream outputStream)
---BufferedOutputStream(OutputStream outputStream, int bufSize)
---第一种形式创建了一个使用512字节缓冲区的缓冲流。
---第二种形式,缓冲区的大小用bufSize参数传入。
要想在程序结束之前将缓冲区里的数据写入磁盘,除了填满缓冲区或关闭输出流外,还可以显示调用flush()方法。Flush()方法的声明为:
---public void flush() throws IOException
BufferedInputStream(缓冲输入流):
---public void mark(int readlimit):在此输入流中标记当前的位置。对reset方法的后续调用会在最后标记的位置重新定位此流,以便后续读取重新读取相同的字节。
---public void reset():将此流重新定位到对此输入流最后调用mark方法时的位置。
缓冲一个输入流同样提供了在可用缓冲区的流内支持向后移动的必备基础。除了在任何InputStream类中执行的read()和skip()方法外,BufferedInputStream同样支持mark()和reset()方法。
BufferedInputStream.markSupported()返回true是这一支持的体现。
当创建缓冲输入流BufferedInputStream时,一个输入缓冲区数组被创建,来自流的数据填入缓冲去,一次课填入许多字节。
缓冲输入/输出是一个非常普通的性能优化。Java的BufferedInputStream类允许把任何InputStream类“包装”成缓冲流并使它的性能提高。
BufferedInputStream有两个构造方法:
---BufferedInputStream(InputStream inputStream)
---BufferedInputStream(InputStream inputStream, int bufSize)
---第一种形式创建BufferedInputStream流对象并为以后的使用保存InputStream参数in,并创建一个内部缓冲区数组来保存输入数据。
---第二种形式用指定的缓冲区大小size创建BufferedInputStrean流对象,并为以后的使用保存InputStream参数in。
缓冲字节流:
若处理的数据量较多,为避免每个字节的读写都对流进行,可以使用过滤流类的子类缓冲流。缓冲流建立一个内部缓冲区,输入输出数据先读写到缓冲区中进行操作,这样可以提高文件流的操作效率。
下面是ByteArrayInputStream和ByteArrayOutputStream两个使用示例:
package com.shengshiyuan.io2; import java.io.ByteArrayInputStream; public class ByteArrayInputStreamTest1 { public static void main(String[] args) { String temp = "abc"; byte[] b = temp.getBytes(); ByteArrayInputStream in = new ByteArrayInputStream(b); for (int i = 0; i < temp.length(); i++) { int c; // 每次会读一个字节 while (-1 != (c = in.read())) { if (0 == i) { // java里面的字符在内存里面都是用数字表示的,用整型来表示的,获取到c之后,c是一个整型,把它转换成字符才能真正显示出来字符的内容。 System.out.println((char) c); } else { // 将字符"(char)c"转换成大写。 System.out.println(Character.toUpperCase((char) c)); } } System.out.println(); // 将缓冲区读的位置重置为标记位置。除非已标记了另一个位置,或者在构造方法中指定了一个偏移量,否则该标记位置是 // 0。【查看API文档,这个在实际开发中用的不多】。可以调用mark()方法来设定读取时回到流的哪个字节的位置上开始读取,不设定的话就回到流的起始位置 in.reset(); } } }
package com.shengshiyuan.io2; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.OutputStream; /** * ByteArrayOutputStream使用示例 * 类: ByteArrayOutputStreamTest1 <br> * 描述: TODO <br> * 作者: fangguanhong fangguanhong@163.com <br> * 时间: Nov 15, 2013 4:34:12 PM */ public class ByteArrayOutputStreamTest1 { public static void main(String[] args) throws Exception { ByteArrayOutputStream f = new ByteArrayOutputStream(); String str = "hello world welcome"; byte[] buffer = str.getBytes(); // 把str对应的字节数组写到f这个流里面 f.write(buffer); // 从f这个流里面得到刚才放进去那个字节数组 byte[] result = f.toByteArray(); // 遍历字节数组,打印每个字符 for (int i = 0; i < result.length; i++) { System.out.println((char) result[i]); } OutputStream os = new FileOutputStream("test.txt"); // 将f里面的字节数组写入到os这个流里面去 f.writeTo(os); f.close(); os.close(); } }
关于io的笔记太多,决定最后还是把笔记里面的两个pdf文档上传到博客文章的附件作为日后查看笔记的地址(IO_1.pdf和IO_2.pdf,老师讲课时候的课件)。上面记录的只作为一个样例查看(比如笔记顺序,模块汇总等等,上面记录的笔记都是比较重要的,并且所有笔记在附件的pdf文档里面都有)。
下面是DataInputStream和DataOutputStream的使用示例:
package com.shengshiyuan.io2; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; /** * DataOutputStream使用示例 * 使用了装饰模式 * 类: DataStream1 <br> * 描述: TODO <br> * 作者: * 时间: Nov 15, 2013 5:30:27 PM */ public class DataStream1 { public static void main(String[] args) throws Exception { // FileOutputStream是节点流,BufferedOutputStream是过滤流,DataOutputStream是过滤流,过滤流可以包装节点流,过滤流也可以包装节点流。 // 单独使用FileOutputStream只能向文件里面写数据,使用BufferedOutputStream表示可以带缓冲的方式写数据,使用DataOutputStream表示可以使用java基本数据类型的方式写数据。 // 综合起来表示我可以向文件当中以缓冲的方式写入java的基本数据类型。也就是所最后生成的dos对象的功能增强了,它现在已经具备三个功能了。 DataOutputStream dos = new DataOutputStream(new BufferedOutputStream( new FileOutputStream("data.txt"))); byte b = 3; int i = 12; char c = 'a'; float f = 3.3f; dos.writeByte(b); dos.writeInt(i); dos.writeChar(c); dos.writeFloat(f); dos.close(); // 上面吧数据写入到文件里面了,下面再读出来。 DataInputStream dis = new DataInputStream(new BufferedInputStream( new FileInputStream("data.txt"))); // 读和写的顺序一定要保持一致 System.out.println(dis.readByte()); System.out.println(dis.readInt()); System.out.println(dis.readChar()); System.out.println(dis.readFloat()); dis.close(); } }
实际项目里面一定会用到的流类有:FileInputStream、FileOutputStream、BufferedInputStream、BufferedOutputStream、ByteArrayInputStream、ByteArrayOutputStream。其他的虽然用,但是用的不多,有的甚至用的很少。
下面开始讲解java io的另一个重要模块:字符流,(上面讲解的都是字节流)。
首先查看字符流的相关pdf文档IO_3.pdf,了解详细知识。并且听完之后把pdf文档里面的笔记重写在这个文档里面记录一遍并且贴到将来的博客文章里面。
尽管字节流提供了处理任何类型输入/输出操作的足够的功能,它们不能直接操作Unicode字符。既然Java的一个主要目的是支持“只写一次,到处运行”的哲学,包括直接的字符输入/输出支持是必要的。本节将讨论几个字符输入/输出类。字符流层次结构的顶层是Reader 和Writer 抽象类。我们将从它们开始。
字符输入/输出类是在java 的1.1版本中新加的。由此,你仍然可以发现遗留下的程序代码在应该使用字符流时却使用了字节流。当遇到这种代码,最好更新它
由于Java采用16位的Unicode字符,因此需要基于字符的输入/输出操作。从Java1.1版开始,加入了专门处理字符流的抽象类Reader和Writer,前者用于处理输入,后者用于处理输出。这两个类类似于InputStream和OuputStream,也只是提供一些用于字符流的规定,本身不能用来生成对象。
Reader和Writer类也有较多的子类,与字节流类似,它们用来创建具体的字符流对象进行I/O操作。字符流的读写等方法与字节流的相应方法都很类似,但读写对象使用的是字符
Reader中包含一套字符输入流需要的方法,可以完成最基本的从输入流读入数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的Reader子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输入方法,如read(),来实现对相应外设的输入操作。
Writer中包含一套字符输出流需要的方法,可以完成最基本的输出数据到输出流的功能。当Java程序需要将数据输出到外设时,可根据数据的不同形式,也要创建一个适当的Writer子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输出方法,如write(),来实现对相应外设的输出操作。
• Reader是定义Java的流式字符输入模式的抽象类。该类的所有方法在出错情况下都将引发IOException 异常 。
• Writer 是定义流式字符输出的抽象类。所有该类的方法都返回一个void 值并在出错条件下引发IOException 异常。
Java.io包中Reader的类层次:
像里面的FilterReader也是过滤类型的,和字节流里面的过滤流使用方式类似。
Java.io包中Writer的类层次:
像里面的FilterWriter也是过滤类型的,和字节流里面的过滤流使用方式类似。
Java 程序语言使用Unicode来表示字符串和字符,Unicode使用两个字节来表示一个字符,即一个字符占16位(一个字节占8位)。
InputStreamReader和OutputStreamWriter两个类是java.io包中用于处理字符流的基本类,用来在字节流和字符流之间搭一座“桥”。这里字节流的编码规范与具体的平台有关,可以在构造流对象时指定规范,也可以使用当前平台的缺省规范。
• InputStreamReader和OutputStreamWriter类的主要构造方法如下
–public InputSteamReader(InputSteam in)
–public InputSteamReader(InputSteam in,String enc)
–public OutputStreamWriter(OutputStream out)
–public OutputStreamWriter(OutputStream out,String enc)
• 其中in和out分别为输入和输出字节流对象,enc为指定的编码规范(若无此参数,表示
使用当前平台的缺省规范,可用getEncoding()方法得到当前字符流所用的编码方式)。
• 读写字符的方法read()、write(),关闭流的方法close()等与Reader和Writer类的同名方法用法都是类似的。
• FileReader类创建了一个可以读取文件内容的Reader类。FileReader继承于InputStreamReader。它最常用的构造方法显示如下
–FileReader(String filePath)
–FileReader(File fileObj)
–每一个都能引发一个FileNotFoundException异常。这里,filePath是一个文件的完整路径,fileObj是描述该文件的File 对象。
• FileWriter 创建一个可以写文件的Writer 类。 FileWriter继承于OutputStreamWriter.它最常用的构造方法如下:
–FileWriter(String filePath)
–FileWriter(String filePath, boolean append)
–FileWriter(File fileObj)
–append :如果为 true,则将字节写入文件末尾处,而不是写入文件开始处
• FileWriter类的创建不依赖于文件存在与否。在创建文件之前,FileWriter将在创建对象时打开它来作为输出。如果你试图打开一个只读文件,将引发一个IOException异常。
• CharArrayReader 是一个把字符数组作为源的输入流的实现。该类有两个构造方法,每一个都需要一个字符数组提供数据源
–CharArrayReader(char array[ ])
–CharArrayReader(char array[ ], int start, int numChars)
–这里,array是输入源。第二个构造方法从你的字符数组的子集创建了一个Reader,该子集以start指定的索引开始,长度为numChars。
• BufferedReader 通过缓冲输入提高性能。它有两个构造方法
–BufferedReader(Reader inputStream)
–BufferedReader(Reader inputStream, int bufSize)
–第一种形式创建一个默认缓冲区长度的缓冲字符流。第二种形式,缓冲区长度由bufSize传入
• 和字节流的情况相同,缓冲一个输入字符流同样提供支持可用缓冲区中流内反向移动的基础。为支持这点,BufferedReader 实现了mark( )和reset( )方法,并且BufferedReader.markSupported( ) 返回true
• BufferedWriter是一个增加了flush( )方法的Writer。flush( )方法可以用来确保数据缓冲区确实被写到实际的输出流。用BufferedWriter 可以通过减小数据被实际的写到输出流的次数而提高程序的性能。
• BufferedWriter有两个构造方法:
–BufferedWriter(Writer outputStream)
–BufferedWriter(Writer outputStream, int bufSize)
–第一种形式创建了使用默认大小缓冲区的缓冲流。第二种形式中,缓冲区大小是由bufSize参数传入的
• ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基于常用的英文字符的一套电脑编码系统。我们知道英文中经常使用的字符、数字符号被计算机处理时都是以二进制码的形式出现的。这种二进制码的集合就是所谓的ASCII码。每一个ASCII码与一个8位(bit)二进制数对应。其最高位是0,相应的十进制数是0-127。如,数字“0”的编码用十进制数表示就是48。另有128个扩展的ASCII码,最高位都是1,由一些制表符和其它符号组成。ASCII是现今最通用的单字节编码系统。
• GB2312:GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集-基本集》。主要用于给每一个中文字符指定相应的数字,也就是进行编码。一个中文字符用两个字节的数字来表示,为了和ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。【用来表示中文的编码格式】
• GBK:为了对更多的字符进行编码,国家又发布了新的编码系统GBK(GBK的K是“扩展”的汉语拼音第一个字母)。在新的编码系统里,除了完全兼容GB2312 外,还对繁体中文、一些不常用的汉字和许多符号进行了编码。 【它是能表示一些生僻的GB2312表示不了的中文】
• ISO-8859-1:是西方国家所使用的字符编码集,是一种单字节的字符集 ,而英文实际上只用了其中数字小于128的部分。【不能表示中文】
• Unicode:这是一种通用的字符集,对所有语言的文字进行了统一编码,对每一个字符都用2个字节来表示,对于英文字符采取前面加“0”字节的策略实现等长兼容。如 “a” 的ASCII码为0x61,UNICODE就为0x00,0x61。(在internet上传输效率较低)
• UTF-8:Eight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,UCS 是所有其他字符集标准的一个超集)。一个7位的ASCII码值,对应的UTF码是一个字节。如果字符是0x0000,或在0x0080与0x007f之间,对应的UTF码是两个字节,如果字符在0x0800与0xffff之间,对应的UTF码是三个字节(汉字为3个字节)。【最通用的一种编码格式,所有的语言都能表示,国际化里面一般都用的这种编码格式】
下面来个小的总结:
• InputStream和OutputStream:字节流的输入输出。
• Reader和Writer:字符流的输入输出。
• 流的链接(Java I/O库的设计原则)
下面是字符流的一些使用示例(重点查看):
package com.shengshiyuan.io2; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class StreamTest { // 使用字符流操作字符串的时候就比使用字节流方便多了,不用一次次将字节转换成字符了(虽然使用字符流的地方使用字节流也能实现,但是没它方便)。 public static void main(String[] args) throws Exception { FileOutputStream fos = new FileOutputStream("file.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos); BufferedWriter bw = new BufferedWriter(osw); bw.write("http://www.google.com"); bw.write("\n"); bw.write("http://www.baidu.com"); bw.close(); FileInputStream fis = new FileInputStream("file.txt"); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); // 固定的代码格式(经常用到) String str = br.readLine(); while (null != str) { System.out.println(str); str = br.readLine(); } br.close(); } }
package com.shengshiyuan.io2; import java.io.BufferedReader; import java.io.InputStreamReader; public class StreamTest2 { public static void main(String[] args) throws Exception { // 将标准输入设备(比如键盘就是标准输入设备,命令行就是标准输出设备)包装成一个字符流 InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String str; while (null != (str = br.readLine())) { System.out.println(str); } br.close(); } }
package com.shengshiyuan.io2; import java.io.BufferedReader; import java.io.FileReader; /** * FileReader使用示例 * 类: FileReader1 <br> * 描述: TODO <br> * 作者: fangguanhong fangguanhong@163.com <br> * 时间: Nov 18, 2013 3:30:53 PM */ public class FileReader1 { // 读取自己的源文件,然后写到命令行里面 public static void main(String[] args) throws Exception { FileReader fr = new FileReader( "c:/FileReader1.java"); // 增加缓冲 BufferedReader br = new BufferedReader(fr); String str; while (null != (str = br.readLine())) { System.out.println(str); } br.close(); } }
package com.shengshiyuan.io2; import java.io.FileWriter; /** * FileWriter使用示例 * 类: FileWriter1 <br> * 描述: TODO <br> * 作者: fangguanhong fangguanhong@163.com <br> * 时间: Nov 18, 2013 3:46:09 PM */ public class FileWriter1 { public static void main(String[] args) throws Exception { String str = "hello world welcome nihao hehe"; char[] buffer = new char[str.length()]; // 从字符串里面将字符拷贝到目标数组里面 str.getChars(0, str.length(), buffer, 0); FileWriter f = new FileWriter("file2.txt"); for (int i = 0; i < buffer.length; i++) { f.write(buffer[i]); } f.close(); } }
package com.shengshiyuan.io2; import java.io.CharArrayReader; /** * CharArrayReader使用示例 * 类: CharArrayReader1 <br> * 描述: TODO <br> * 作者: fangguanhong fangguanhong@163.com <br> * 时间: Nov 18, 2013 4:01:52 PM */ public class CharArrayReader1 { public static void main(String[] args) throws Exception { String temp = "abcdefg"; char[] ch = new char[temp.length()]; // 从字符串里面将字符拷贝到目标数组里面 temp.getChars(0, temp.length(), ch, 0); CharArrayReader input = new CharArrayReader(ch); int i; while (-1 != (i = input.read())) { System.out.println((char) i); } input.close(); } }
RandomAccessFile类比较特殊,即能读,又能写。而且没有继承InputStream和OutputStream。这个类了解下就可以。
把IO_1.pdf和IO_2.pdf上传附件即可,IO_3.pdf和Decorator.pdf已经在笔记里面总结完了。
附件里面的IO_2.zip里面装IO_2.pdf,IO_1.zip里面装IO_1.pdf
发表评论
-
领域精通涉及技术点(不分先后)
2017-12-20 19:35 620Java8 netty jvm kafaka消息队列 上传下载 ... -
计算机各种单位讲解及换算
2017-12-13 13:54 1642我还听过有UK的 一、最小单位:位(bit,缩写为b) 在原 ... -
JAVA字符串格式化-String.format()和MessageFormat的使用
2017-12-05 10:39 1447String.format()常规类型的格式化 Stri ... -
eclipse启动项目常见问题
2017-11-16 17:46 1184今儿遇到了个问题,ecli ... -
字符编码笔记:ASCII,Unicode和UTF-8
2017-10-23 16:37 458讲的太牛逼了: http://ww ... -
emoji简单讲解
2017-10-23 15:17 973emoji处理方式大起底 http://blog.csdn.n ... -
BigDecimal讲解
2017-10-12 15:58 445BigDecimal 由任意精度的整数非标度值 和 32 位的 ... -
eclips 控制台console上不打印信息
2017-09-06 21:53 5811、进windows菜单 -> show view -& ... -
详解RequestMappingHandlerMapping和RequestMappingHandlerAdapter
2017-08-29 17:08 2981http://donald-draper.iteye.com/ ... -
用@ExceptionHandler 来进行切面异常处理
2017-08-29 11:47 2311有时候我们想处理某个类里Controller中抛出的异常怎么搞 ... -
Spring 注解@Component、@Repository、@Service、@Controller区别
2017-08-28 15:27 1017spring 2.5 中除了提供 @Com ... -
线程的一点小总结
2017-08-23 20:36 709java中main方法启动的是一个进程还是一个线程? 答:是一 ... -
线程池
2017-08-23 17:35 522诸如Web 服务器、数据库 ... -
Class源码大概讲解
2017-08-23 16:47 512http://blog.csdn.net/a327369238 ... -
Spring 事务相关
2017-08-14 12:10 476Transactionz注解的readOnly ... -
把时间当做朋友-前言
2017-08-13 20:47 407要管理的不是时间,而是自己。人们生活在同一个世界,却又各自 ... -
单例里面的方法讲解
2017-08-11 14:55 490spring里的controller是单例的。系统针对每个co ... -
eclipse拷贝出来的项目名称还是原来的
2017-07-26 16:46 1082需要修改的有如下几个地方: 1、pom.xml里面打包的名字一 ... -
自定义hibernate方言,新增自定义函数
2017-06-27 10:47 880按位与运算(&)在许多数据库中都是支持的,遗憾的是,H ... -
http请求参数:header body paramter三种参数区别、联系
2017-06-19 10:46 489112345
相关推荐
有关Java输入输出流的总结有关Java输入输出流的总结有关Java输入输出流的总结
Java IO总结 Java IO是Java中对文件的操作方式,以流的方式进行。流是Java内存中的一组有序数据序列。Java将数据从源(文件、内存、键盘、网络)读入到内存中,形成了流,然后将这些流还可以写到另外的目的地(文件...
Java io流的总结
JavaIO总结[借鉴].pdf
javaIO总结,帮助初学者了解及掌握IO,以及java高级的一些基础知识
java基础中的IO流部分的总结,有详细的知识点描述,思维导图的整体框架
Java IO系统主要包括两个包:`java.io`和`java.nio`(New IO),其中`java.io`提供了一系列基于流的I/O操作接口与实现类,而`java.nio`则提供了更高效的数据访问方式,如通道和缓冲区等。 Java IO系统的设计原则之...
JAVA_IO流学习总结
Java IO流总结 Java IO流是Java语言中最基本和最重要的输入/输出机制,负责将数据从外部世界输入到Java应用程序中或将数据从Java应用程序输出到外部世界。IO流可以分为两大类:字节流和字符流。 1. 节点流:离数据...
这篇详细的总结将围绕Java IO体系结构、核心类、流的概念、缓冲区、转换流、字符集、文件操作、对象序列化以及NIO(非阻塞IO)等多个方面进行展开。 一、Java IO体系结构 Java IO体系是Java平台中用于处理数据输入...
这是别人总结的很有实用价值的javaIO流教程。
下面是对Java IO流的详细总结: 1. 流的概念: 流是一种抽象的数据传输方式,可以将数据从一个地方传输到另一个地方。Java中的流分为输入流和输出流,分别用于读取和写入数据。流按照处理数据的不同类型,又可以...
总结来说,Java NIO提供了一种更高效、更适合处理并发的IO模型,尤其在服务器端开发中,如高并发的网络应用,NIO的优势更为明显。理解和掌握Java IO与NIO的使用,对于提升Java应用程序的性能和可扩展性至关重要。
总结来说,Java IO流是一个庞大的体系,覆盖了从基础的文件操作到复杂的网络通信,理解并熟练掌握这一部分将极大地提升Java开发者的技能。通过学习和实践,开发者可以灵活地处理各种数据输入输出场景,为应用程序...
#### 五、Java IO总结 Java IO是一个强大的框架,它支持各种不同的流类型,包括字节流和字符流。通过使用装饰模式,开发人员可以轻松地扩展流的功能,而无需修改原始流的实现。这种灵活性使得Java IO成为处理文件和...
在这个大总结中,我们将深入探讨Java IO流的基本概念、分类、常用类以及实践应用。 1. **基本概念** - **流(Stream)**:在Java中,流是一个抽象的概念,代表数据的有序序列。它可以是字节流或字符流,流向可以是...
这篇博客“Java学习之IO总结及mina和netty”探讨了Java IO的基础知识,并深入到两个高级网络通信框架——Mina和Netty。Mina和Netty都是基于NIO(非阻塞IO)的高性能网络应用框架,它们简化了复杂网络编程的实现。 *...