IO流

基本IO与OS

按照流的方向主要分为输入流和输出流。

数据流按照数据单位的不同分为字节流和字符流。

按照功能可以划分节点流和处理流。

节点流与处理流

按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。

节点流:可以从或向一个特定的地方(节点)读写数据。

处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。

 处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

 通常节点流也称为低级流。

通常处理流也称为高级流或过滤流。

输入和输出

什么是输入?

输入是一个从外界到程序的方向,通常为们需要"读取"外界的数据时,使用输入。所以输入是用来读取数据的。

什么是输出?

输出是一个从程序送到外界的方向,通常我们需要"写出"数据到外界时,使用输出,所以输出时用来写出数据的。

输入流

所有的输入流都是InputStream抽象类(字节输入流)和Reader抽象类(字符输入流)的子类。其中ImputStream类是字节输入流的抽象类,是所有字节输入流的父类。

InputStream类中所有方法遇到错误时都会引发IOException异常。

Java的文本输入流Readar类,该类是字符输入流的抽象类,即所有的字符输入流和实现都是它的子类。

常用方法:

int read():从输入流读入一个 8 字节的数据,将它转换成一个 0~255 的整数,返回一个整数,如果遇到输入流的结尾返回 -1。

int read(byte[] b):从输入流读取若干字节的数据保存到参数 b 指定的字芳数组中,返回的字芾数表示读取的字节数,如果遇到输入流的结尾返回 -1。

int read(byte[] b,int off,int len):从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,其中 off 是指在数组中开始保存数据位置的起始下标,len 是指读取字节的位数。返回的是实际读取的字节数,如果遇到输入流的结尾则返回 -1。

void close():关闭数据流,当完成对数据流的操作之后需要关闭数据流。

int available():返回可以从数据源读取的数据流的位数。

skip(long n):从输入流跳过参数 n 指定的字节数目。

boolean markSupported():判断输入流是否可以重复读取,如果可以就返回 true。

void mark(int readLimit):如果输入流可以被重复读取,从流的当前位置开始设置标记,readLimit 指定可以设置标记的字苟数。

void reset():使输入流重新定位到刚才被标记的位置,这样可以重新读取标记过的数据。

注意:

最后 3 个方法一般会结合在一起使用,首先使用 markSupported() 判断,如果可以重复读取,则使用 mark(int readLimit) 方法进行标记,标记完成之后可以使用 read() 方法读取标记范围内的字节数,最后使用 reset() 方法使输入流重新定位到标记的位置,继而完成重复读取操作。

输出流

在Java中所有的输出流都是OutputStream抽象类(字节输出流)和Writer抽象类(字符输出流)的子类。其中OutputStream类是字节输出流的抽象类,是所有字节输出流的父类。

字符输出流的父类是 Writer

常用方法:

nt write (b):将指定字节的数据写入到输出流。

int write (byte[] b):将指定字节数组的内容写入输出流。

int write (byte[] b,int off,int len):将指定字节数组从 off 位置开始的 len 字芳的内容写入输出流。

close():关闭数据流,当完成对数据流的操作之后需要关闭数据流。

flush():刷新输出流,强行将缓冲区的内容写入输出流。

IS和OS常用方法

InputStream是所有字节输入流的父类,其定义了基础的读取方法,常用的方法如下:

       int read()           

读取一个字节,以int形式返回,该int值的"低八位"有效,若返回值为-1则表示EOF

  int read(byte[] d)

尝试最多读取给定数组的length个字节并存入该数组,返回值为实际读取到的字节量。

 OutputStream是所有字节输出流的父类,其定义了基础的写出方法,常用的方法如下:

      void write(int d)

写出一个字节,写的是给定的int的"低八位"

  void write(byte[] d)

将给定的字节数组中的所有字节全部写出

文件流

创建FOS对象(重写模式)

FileOutputStream是文件的字节输出流,我们使用该流可以以字节为单位将数据写入文件。

 构造方法:

       FileOutputStream(File file)

//创建一个向指定File对象表示的文件中写出数据的文件输出流。

 FileOutputStream(String filename)

//创建一个向具有指定名称的文件中写出数据的文件输出流。

FileInputStream是文件的字节输入流,我们使用该流可以以字节为单位从文件中读取数据。

FileInputStream有两个常用的构造方法:

FileInputStream(File file)

创建一个从指定File对象表示的文件中读取数据的文件输入流。

FileInputStream(String name)

创建用于读取给定的文件系统中的路径名name所指定的文件的文件输入流

read()和write(int d)方法

FileInputStream继承自InputStream,其提供了以字节为单位读取文件数据的方法read。

  int read()

从此输入流中读取一个数据字节,若返回-1则表示EOF(End Of File)

 FileOutputStream继承自OutputStream,其提供了以字节为单位向文件写数据的方法write。

  void write(int d)

将指定字节写入此文件输出流,这里只写给定的int值的"低八位"

read(byte[] d)和write(byte[] d)方法

FileInputStream也支持批量读取字节数据的方法:

      int read(byte[] b)

从此输入流中将最多b.length个字节的数据读入到字节数组b中

FileOutputStream也支持批量写出字节数据的方法:

 void write(byte[] b)

将b.length个字节从指定byte数组写入此文件输出流中。

 void write(byte[] b,int offset,int len)

将指定byte数组中从偏移量offset开始的len个字节写入此文件输出流。

缓冲流

使用缓冲输出流可以提高写出效率,但是这也存在着一个问题,就是写出数据缺乏即时性。有时我们需要在执行完某些写出操作后,就希望将这些数据即时写出,而非在缓冲区中保存直到缓冲区满后才写出。这时我们可以使用缓冲流的一个方法flush。

     void flush()

清空缓冲区,将缓冲区中的数据强制写出。

实例:

    public void b()throws Exception{
//创建缓冲字节输入流
FileInputStream f=new FileInputStream("OO.java");
BufferedInputStream bff=new BufferedInputStream(f);
int d=1;
//缓冲读入,实际上并非是一个字节一个字节从文件读取的。
while((d=bff.read())!=-1) {
System.out.println(d+"");
}
bff.close();
}
}

对象流

对象序列化概念

· 对象是存在于内存中的。有时候我们需要将对象保存到硬盘上,又有时我们需要将对象传输到另一台计算机上等等这样的操作。这时我们需要将对象转换为一个字节序列,而这个过程就称为对象序列化。相反,我们有这样一个字节序列需要将其转换为对应的对象,这个过程就称为对象的反序列化。

使用OOS实现对象序列化

· ObjectOutputStream是用来对对象进行序列化的输出流。

· 其实现对象序列化的方法为:

void writeObject(Object o)

该方法可以将给定的对象转换为一个字节序列化后写出。

使用OIS实现对象反序列化

 · ObjectInputStream是用来对对象进行反序列化的输入流。

· 其实现对象反序列化的方法为:

        - Object readObject()

       该方法可以从流中读取字节并转换为对应的对象。  

 Serializable接口

    · ObjectOutputStream在对对象进行序列化时有个要求,就是需要序列化的对象所属的类必须实现Serializable接口。

· 实现该接口不需要重写任何方法。其只是作为可序列化的标志。

    ·  通常实现该接口的类需要提供一个常量serialVersionUID,表明该类的版本。若不显示的声明,在对象序列化时也会根据当前类的各个方面计算该类的默认serialVersionUID,但不同平台编译器实现有所不同,所以若想跨平台,都应显示的声明版本号。

Serializable接口(续1)

· 如果声明的类的对象序列化存到硬盘上面,之后随着需求的变化更改了类的属性(增加或减少或改名),那么当反序列化时,就会出现InvalidClassException,这样就会造成不兼容性的问题。

但当serialVersionUID相同时,它就会将不一样的field以type的预设值反序列化,可避开不兼容性问题。

transient关键字

 · 对象在序列化后得到的字节序列往往比较大,有时我们在对一个对象进行序列化时可以忽略某些不必要的属性,从而对序列化后得到的字节序列"瘦身"。

· 关键字transient

· 被该关键字修饰的属性在序列化时其值将被忽略。

Day02:基本IO操作的更多相关文章

  1. [.NET] 利用 async & await 进行异步 IO 操作

    利用 async & await 进行异步 IO 操作 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6082673.html  序 上次,博主 ...

  2. 文件IO操作..修改文件的只读属性

    文件的IO操作..很多同行的IO工具类都是直接写..但是如果文件有只读属性的话..则会写入失败..所以附加了一个只读的判断和修改.. 代码如下: /// <summary> /// 创建文 ...

  3. python之协程与IO操作

    协程 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B ...

  4. JAVASE02-Unit08: 文本数据IO操作 、 异常处理

    Unit08: 文本数据IO操作 . 异常处理 * java.io.ObjectOutputStream * 对象输出流,作用是进行对象序列化 package day08; import java.i ...

  5. JAVASE02-Unit07: 基本IO操作 、 文本数据IO操作

    基本IO操作 . 文本数据IO操作 java标准IO(input/output)操作 package day07; import java.io.FileOutputStream; import ja ...

  6. IO操作概念。同步、异步、阻塞、非阻塞

    “一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作. 同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO. 阻塞IO和非阻塞IO的区别在于第 ...

  7. Java基础复习笔记系列 七 IO操作

    Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...

  8. java中的IO操作总结

    一.InputStream重用技巧(利用ByteArrayOutputStream) 对同一个InputStream对象进行使用多次. 比如,客户端从服务器获取数据 ,利用HttpURLConnect ...

  9. Linux系统编程--文件IO操作

    Linux思想即,Linux系统下一切皆文件. 一.对文件操作的几个函数 1.打开文件open函数 int open(const char *path, int oflags); int open(c ...

随机推荐

  1. Angular与Vue

    最近在考虑对前端js框架的选择 根据前人的总结,就总结一下 Angular与Vue 的特点与区别 速度/性能 虽然 Angular 和 Vue 都提供了很高的性能,但由于 Vue 的虚拟 DOM 实现 ...

  2. python+Appium自动化:Appium-desktop界面简介

    Appium Desktop是一款适用于Mac,Windows和Linux的开源应用程序,提供了更加优化的图形界面. Appium Desktop是由Simple.Advanced.Presets三个 ...

  3. MFC总结

    1.首先是ListControl 简介: 列表视图控件List Control同样比较常见,它能够把任何字符串内容以列表的方式显示出来,这种显示方式的特点是整洁.直观,在实际应用中能为用户带来方便. ...

  4. 《Python基础教程》第二章:列表和元组(1)

    列表可以修改,元组则不能 字符串就是一个由字符组成的序列 使用分片操作来访问一定范围内的元素,分片操作的实现需要提供两个索引作为边界,第一个索引的元素是包含在分片内的,而第二个不包含在分片内. 如果分 ...

  5. solr admin界面的监控

    这里可以看到,solr的版本,lucene的版本,jvm的版本,CPU核数,jvm启动参数,还有物理内存占用,交换空间占用,jvm内存占用. 这里可以看到每个core的情况. 这里可以看到java的所 ...

  6. ionic使用CardIO实现扫描银行卡功能(只能扫描16位以下,并且是浮雕数字)

    在一些涉及支付功能的app,一般需要绑定银行卡,除了靠用户手动输入银行卡号,用手机扫描银行卡也是一种常用的手段,查阅了写资料,发现ionic有CardIO插件可以实现这个功能,就兴致冲冲去尝试,结果有 ...

  7. Vue 实现 登陆后打开主页面(登陆组件 + 主页面组件)

    本次演示,项目所需iview,router 首先 在 views 目录 新建 两个 组件 ( login.vue ,index.vue ) login.vue <template> < ...

  8. hadoop中的JournalNode

    1.在HADOOP扮演的角色 JournalNode是在MR2也就是Yarn中新加的,journalNode的作用是存放EditLog的, 在MR1中editlog是和fsimage存放在一起的然后S ...

  9. python 多线程实现循环打印 abc

    python 多线程实现循环打印 abc 好久没写过python了, 想自己实践一下把 非阻塞版 import threading import time def print_a(): global ...

  10. flask框架(九): 请求和响应扩展以及中间件

    一:请求响应扩展 # 每一次访问都执行 # 注意请求之前按照顺序执行 # 请求之后按照书写顺序倒序执行 # 请求之前执行 @app.before_request def process_request ...