Java中IO流总介

来源:互联网 发布:nba2kol熊猫挂机软件 编辑:程序博客网 时间:2024/06/05 10:17

Java中的IO流主要分为:四种(8个主要相关的类,其中前4个为顶级类)

按流向分:输入流和输出流
按性质分:原始流和装饰流
按类型分:字节流和字符流

1.原始字节流,inputstream和outputstream,
  用于读取诸如图片,视频,音频等的原始字节文件,一个一个字节读,效率低。
2.在字节流的基础上使用IuputStreamReader装饰成的字符流,reader和writer。
  文件中包含汉字等非单字节字符时使用,一个字符一个字符读,效率低。
3.在原始字节流的基础上装饰的带缓存的字节流。BufferedInputStream,BufferedOutputStream。
  带缓存的一个字节一个字节读,可以用来读取原始的图片等数据,替换原始的InputStream,效率高。
4.在字符流的基础上装饰的带缓存的字符流。BufferedReader和BufferedWriter,分别新增readLine()和newLine()方法,
  一个缓存一个缓存读,效率高。



---------------------------------------------------------
输出流特例 --- 2种打印流
PrintStream(字节输出流)  -- 在其他输出流的基础上添加了许多新的功能。
  1.没有对应的输入流
  2.可以写入:基本数据类型,字符串,对象,数组等所有的数据类型
  3.带有自动行刷新功能,但必须在构造方法中开启刷新功能,默认不带有刷新功能。
  4.在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。
  5.PrintStream虽然是操作字节的,但是因为具有println等换行功能,所以不能用来写入原始的图片,音频等数据。

System.out(标准输出:默认输出到控制台):返回的是PrintStream类的实例
System.in(标准输入:默认为键盘):返回的是InputStream类的实例
System.err(标准错误输出流:默认红色输出到控制台)三者均返回的是PrintStream类的实例。
这些默认的输入输出位置可以使用System类中的setIn(),setOut(),setErr()方法来更改设置:
如更改输出位置为指定文件:
//指定输出流位置:
System.out.println("我被输出到控制台!");
System.setOut(new PrintStream("E://test//test1.txt"));
System.setErr(new PrintStream("E://test//test2.txt"));
System.out.println("我被输出到指定的位置!!");
System.err.println(我被输出到test2.txt文件);

//指定输入流位置
System.setIn(new InputStream("E://test//test.txt"));
InputStream in = System.in;
//从该输入流in中获取数据
byte[] buffer = new byte[1024];
int length = -1;
while((length = in.read(buffer)) != -1){
  System.out.println(new String(buffer,0,length));
}
----------------------------------------------------------
PrintWriter(字符输出流)  
  1.在BufferedWriter上的再一次封装,即在原始字节输出流上的三次装饰。
    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new OutputStream("E://test.txt")));
  2.默认不带自动刷新功能,可通过第二个参数指定,如果指定为true,那么println、printf 或 format 方法将刷新输出缓冲区
  3.可以写入基本数据类型,对象,数组,字符串等所有的数据。

两者中建议使用PrintWriter

-----------------------------------------------------------
不使用Scanner,读取键盘录入???
第一种方式,一个字节一个字节读:
  InputStream in = System.in;
  //读取流
  Byte[] buffer = new byte[1024];
  int length = -1;
  while((length = in.read(buffer))!=-1){
     System.out.println(new String(buffer,0,length));
  }
第二种方式:因为用户可能会输入汉字,所以应该使用字符流:
   InputStream in = System.in;
   Reader reader = new InputStreamReader(in);
  //读取流
  char[] buffer = new char[1024];
  int length = -1;
  while((length = reader.read(buffer))!=-1){
     System.out.println(new String(buffer,0,length));
  }
第三种方式:带缓存的字符流,可以按行读取,并且高效
  InputStream in = System.in;
  BufferedReader reader = new BufferedReader(new InputStreamReader(in));
  String str = "";
  while((str = reader.readLine())!=null){
     System.out.println(str);
  }
------------------------------------------------------------------------------------

以上获取到str之后,使用带缓存的字符流读取到的是字符串,可以实现字符串和基本数据类型之间的转换,
然后就可以获取到基本数据类型的结果,就达到了和Scanner一样的效果,查看Scanner源码实现。
---------------------------------------------------------------------------------------
模拟系统Scanner类编写自己的MyScanner类的思路:

--------------------------------------------------------------------------------------------------------
Object流:用来传输对象信息,包括字符串和数组,并且一次可以写入多个对象,在取时顺序和类型与写入时一致。
例如用户登录时可以将用户名和密码封装成一个JavaBean对象,将该对象的信息保存到本地的.tmp文件中。
使用场景:在main方法中,创建一个Person对象,给各属性赋值完了之后将该对象信息保存到本地的.tmp文件中。

使用条件:
1.该对象要实现Serializable接口可序列化
2.可以写入各种类型的数据。
3.不能序列化静态变量
4.如果存储了多个对象,那么取出顺序和存入的顺序一致

对象的写又被称为:序列化
对象的读又被称为:反序列化

对象输出流:ObjectOutputStream对象的创建:

对象输入流:ObjectInputStream
扩展:所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,
     根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。因此,
     为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。
     还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),
     原因是这种声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没有用处。
----------------------------------------------------------------------------------------------------
Data流:用来写出和读入基本数据类型,读取的顺序与写入的顺序一致。

------------------------------------------------------------------------------------------------------
内存流:
流的源和目的地除了可以是文件外,还可以是计算机内存。
字节输入流ByteArrayInputStream和字节输出流ByteArrayOutputStream分别使用字节数组作为流的源和目标。
//从网络获取数据使用内存流,数据大小,类型不确定

public static byte[] read(InputStream input) throws Exception{
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
//read方法的返回值为int类型的数据,如果返回-1代表数据读取完
int len = 0;
//使用while循环将数据读取到一个字节数组中
while((len = input.read(buffer)) != -1){
//一边读一边存放数据
out.write(buffer, 0, len);
}
//关闭流
input.close();
//返回内存中的数据
return out.toByteArray();
}

使用的目的:将网络文件读取缓存到内存中,以后每次读取直接从内存中读取,节省了流浪和时间,也可以快速获取。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 房东不想续租了怎么办 唯一住房卖掉后户口怎么办 杭州唯一住房卖掉后户口怎么办 唯一一套住房卖掉户口怎么办 房租押金条丢了怎么办 二建证书跟毕业证丢失怎么办 住宅房到70年怎么办 护照号变了机票怎么办 苹果se指纹坏了怎么办 月经推迟怎么办才能快点来 车载支架不粘了怎么办 otpc平板电脑无法开机怎么办 手表表轴掉了怎么办 鸡肉放冰箱臭了怎么办 鸡胸肉熟了腥怎么办 梦幻西游手游手机号换了怎么办 ppt做一半卡住了怎么办 吃了发霉的蚝油怎么办 蛋皮干燥起皮怎么办 wps卡顿资料没保存怎么办 手指受伤肉掉了怎么办 手机被wifi禁了怎么办 母乳一边是咸的怎么办 tcl电视蓝频了怎么办 长虹电视蓝频了怎么办 电视突然蓝频了怎么办 海信电视蓝频了怎么办 连网电视蓝频了怎么办 英雄联盟画面卡顿怎么办 长残了怎么办原来很帅 被吓到了怎么办没精神 宝宝吓着怎么办最有效 4个月婴儿易惊吓怎么办 心里有问题的人怎么办 减肥的时候想吃东西怎么办 大联盟ping很高怎么办 酷派手机弹广告怎么办 孕早期肚子紧绷怎么办 怀孕2个月同房了怎么办 怀孕前三月同房了怎么办 人流前三天同房了怎么办