Java的IO类都在java.io包下,这些类大体可分为如下4种:java
基于字节操做的IO接口分别是InputStream和OutputStream,InputStream的类结构图以下所示:网络
同InputStream相似,OutputStream类也有着相同的类结构图。app
关于各个子类的使用能够参考JDK 的 API 说明文档,这里咱们须要注意的是:操做数据的方式是能够组合的,以下所示:异步
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("h:\\haha.txt"), "utf-8");
从上面代码能够看出,InputStreamReader能够从FileInputStream中读取数据,从源码中能够看出来,其实不只是InputStreamReader,全部的IO类均可以以这种方式来组合使用。编码
还有一点须要注意的是必须制定流最终写入到什么地方,是磁盘仍是网络,从OutputStream类图中能够看出,写入网络中实际也是写文件操做,只不过底层是经过网络传输了。spa
不论是磁盘仍是网络数据传输,都是以字节为单位的,可是程序中通常常见的数据操做都是以字符为单位的(Java中char占用2字节,C/C++中 char占用1字节),这就须要咱们有一个操做字符的IO接口,来处理字符与字节见的编码转换问题,也就是Write和Reader接口及其实现类,他们 两者的类接口图以下:操作系统
读字符接口Reader的最主要操做方法为read(),其读取字符并返回读取的字符数,不论是 Writer 仍是 Reader 类它们都只定义了读取或写入的数据字符的方式,也就是怎么写或读,可是并无规定数据要写到哪去(好比磁盘或者网络)。线程
有时数据持久化和网络传输是以字节进行的,全部须要字节和字符之间的相互转换。code
/** * 使用FileReader进行读取文件 */ @Test public void testFileReader() throws IOException { FileReader fileReader = new FileReader("h:\\haha.txt"); char[] buff = new char[512]; StringBuffer stringBuffer = new StringBuffer(); while (fileReader.read(buff) > 0) { stringBuffer.append(buff); } fileReader.close(); System.out.print(stringBuffer.toString()); } /** * 使用FileReader进行读取文件,而后FileWriter写入另外一个文件 */ @Test public void testFileReaderAndFileWriter() throws IOException { FileReader fileReader = new FileReader("h:\\haha.txt"); char[] buff = new char[512]; StringBuffer stringBuffer = new StringBuffer(); while (fileReader.read(buff) > 0) { stringBuffer.append(buff); } System.out.println(stringBuffer.toString()); FileWriter fileWriter = new FileWriter("h:\\haha2.txt"); fileWriter.write(stringBuffer.toString().trim()); fileWriter.close(); System.out.println("写入文件成功"); } /** * 使用InputStreamReader进行读取文件 */ @Test public void testInputStreamReader() throws IOException { InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("h:\\haha.txt"), "utf-8"); char[] buff = new char[512]; StringBuffer stringBuffer = new StringBuffer(); while (inputStreamReader.read(buff) > 0) { stringBuffer.append(buff); } System.out.println(stringBuffer.toString()); } @Test public void testIntputStream2() throws IOException { InputStreamReader inputStreamReader = new InputStreamReader(new StringBufferInputStream("hello world")); char[] buff = new char[512]; int n = inputStreamReader.read(buff); System.out.println(n); System.out.println(buff); } /** * 使用inputStreamReader进行读取文件,而后OutputStreamWriter写入另外一个文件 */ @Test public void testOutputStreamWriter() throws IOException { InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("h:\\haha.txt"), "utf-8"); char[] buff = new char[512]; StringBuffer stringBuffer = new StringBuffer(); while (inputStreamReader.read(buff) > 0) { stringBuffer.append(buff); } System.out.println(stringBuffer.toString()); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("h:\\haha2.txt"), "utf-8"); outputStreamWriter.write(stringBuffer.toString().trim()); outputStreamWriter.close(); }
注意:FileReader类继承了InputStreamReader,FileReader读取文件流,经过StreamDecoder解码成char,其解码字符集使用的是默认字符集。在Java中,咱们应该使用File对象来判断某个文件是否存在,若是咱们用FileOutputStream或者FileWriter打开,那么它确定会被覆盖。对象
同步和异步是针对IO来讲的。所谓同步就是一个任务的完成须要依赖另一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态能够保持一致。而异步是不须要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工做,依赖的任务也当即执行,只要本身完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务没法肯定,因此它是不可靠的任务序列。咱们能够用打电话和发短信来很好的比喻同步与异步操做。
阻塞和非阻塞是针对CPU来讲的。阻塞与非阻塞主要是从 CPU 的消耗上来讲的,阻塞就是 CPU 停下来等待一个慢的操做完成 CPU 才接着完成其它的事。非阻塞就是在这个慢的操做在执行时 CPU 去干其它别的事,等这个慢的操做完成时,CPU 再接着完成后续的操做。虽然表面上看非阻塞的方式能够明显的提升 CPU 的利用率,可是也带了另一种后果就是系统的线程切换增长。增长的 CPU 使用时间能不能补偿系统的切换成本须要好好评估。
Java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并可以在之后将这个字节序列彻底恢复为原来的对象。这一过程可经过网络进行,这样序列化机制可以自动弥补不一样操做系统之间的差别。对应序列化的聪明之处在于它不只保存了对象的“全景图”,并且可以追踪到对象自所包含的引用,并保存这些对象;接着又可以对对象内包含的每一个这样的引用进行最终;以此类推。
要实例化一个对象,首先建立某些OutputStream对象,而后将其封装在一个ObjectOutputStream对象内,这是,只须要调用writeObject()便可将对象序列化,并将其发送到OutputStream(对象序列化基于字节,所以使用InputStream和OutputStream继承类层次结构)。反序列化和序列化过程正好相反,须要将一个InputStream封装在ObjectInputStream内,而后调用readObject()获取一个引用,它指向一个向上转型的Object,因此必须向下转型才能直接设置它们。下面是序列化和反序列化示例代码:
@Test public void testWriteSerialization() { try { FileOutputStream fileOutputStream = new FileOutputStream("h:\\serialize.txt"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject("start"); objectOutputStream.writeObject(new Person("luoxn28", 23)); objectOutputStream.writeObject(12); objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println("end..."); } @Test public void testReadSerialization() { try { FileInputStream fileInputStream = new FileInputStream("h:\\serialize.txt"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); String info1 = (String) objectInputStream.readObject(); Person person = (Person) objectInputStream.readObject(); int num = (int) objectInputStream.readObject(); System.out.println(info1); System.out.println(person); System.out.println(num); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
参考资料:
二、Java IO系统