Java的IO流详细总结(二)

Java的IO流(二)
(一)Properties集合
1、集合特点
该集合通常用于操作带键值对的配置文件
【1】集合中的key和value都是String类型
【2】集合的数据可以写入流中,也可以从流中获取
2、Properties的应用
(1)例如,下面程序是演示如何存入和读取数据
Properties properties = new Properties();
properties.setProperty(“s001”, “zhangsan”);
properties.setProperty(“s002”, “lisi”);
properties.setProperty(“s003”, “wangwu”);
properties.setProperty(“s004”, “zhaoliu”);
properties.setProperty(“s005”, “sunqi”);

      Set<String> stringPropertyNames = properties.stringPropertyNames();
      for(String name:stringPropertyNames)
      {
            String value=properties.getProperty(name);
            System.out.println(name+"====="+value);
      }

(2)集合关联流
Properties properties = new Properties();
properties.setProperty(“s001”, “zhangsan”);
properties.setProperty(“s002”, “lisi”);
properties.setProperty(“s003”, “wangwu”);
properties.setProperty(“s004”, “zhaoliu”);
properties.setProperty(“s005”, “sunqi”);

      FileOutputStream fileOutputStream = new FileOutputStream("test.txt");
      properties.store(fileOutputStream, “this is test”);
      fileOutputStream.close();

(3)修改集合信息
//1、读取这个文件
File file=new File(“test.txt”);
if(!file.exists()){
file.createNewFile();
}
FileReader fileReader = new FileReader(“test.txt”);
//2、创建Properties对象
Properties properties = new Properties();
//3、将流信息加载到集合中
properties.load(fileReader);
//4、修改集合信息
properties.setProperty(“11111”, “qqqq”);
//5、将集合信息保存
FileWriter fileWriter = new FileWriter(file);
properties.store(fileWriter, “aaaaa”);
fileReader.close();
fileWriter.close();

(二)打印流
(1)、为什么要用打印流
打印流能方便的打印各种数据值的表现形式,并且不会抛IO异常
(2)、打印流的使用
PrintStream
PrintStream提供了一系列的print()和println(),可以实现将基本数据类型格式化成字符串输出。对象类型将先调用toString(),然后输出该方法返回的字符串
System.out就是PrintStream的一个实例,代表显示器
System.err 也是PrintStream的一个实例,代表显示器
PrintStream的输出功能非常强大,通常需要输出文本内容,都可以将输出流包装成PrintStream后进行输出
PrintStream的方法都不抛出IOException
PrintWriter
PrintStream的对应字符流,功能相同,方法对应
PrintWriter的方法也不抛出IOException
复制文件时可以使用PrintWriter代替BufferedWriter完成将更简单
1、字节流PrintStream
write(int b)方法:将指定的字节写入,写入协议规定,向输出流写一个字节,要写入的字节是参数b的8个低位,b的24个高位将被忽略,例如:97如果按照32机型来算,其二进制的体现形式为
00000000 00000000 00000000 01100001
PrintStream out=new PrintStream(“test.txt”);
out.write(97);
out.close();
由于97处于低8位,运行结果没有问题
但是,数据格式如果是下列结果:
00000000 00000000 00001110 01100001
其十进制数位3681
PrintStream out=new PrintStream(“test.txt”);
out.write(3681);
out.close();
由于3681中的01100001处于低8位,按照协议运行结果输出低8位01100001为97,高位将被忽略
2、字符流PrintWriter
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
PrintWriter out=new PrintWriter(System.out);
//PrintWriter out=new PrintWriter(new FileWriter(“out.txt”));
String line=null;
while((line=bufr.readLine())!=null){
if(“ok”.equals(line)){//如果按下ok退出程序
break;
}
out.print(line);
}
out.close();
bufr.close();
}

(三)序列流
1、SequenceInputStream序列流的作用
SequenceInputStream表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件的末尾,接着从第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止
例如:
Vector vector = new Vector();
vector.add(new FileInputStream(“a.txt”));
vector.add(new FileInputStream(“b.txt”));
vector.add(new FileInputStream(“c.txt”));
Enumeration en=vector.elements();
SequenceInputStream sis=new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream(“d.txt”);
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
2、文件切割
//用读取流关联源文件
FileInputStream fis=new FileInputStream(new File());
//定义一个缓冲区
byte[] buf=new byte[1024*1024];
//创建目的
FileOutputStream fos=null;
File dir=new File(“c:\partfiles”);
if(!dir.exists()){
dir.mkdirs();
}
int len=0;
int count=0;
while((len=fis.read(buf))=-1){
fos=new FileOutputStream(new File(dir,(count++)+".part"));
fos.write(buf,0,len);
}

3、文件的合并
ArrayList list=new ArrayList();
for(int x=1;x<=3;x++)
{
list.add(new FileInputStream(new File(dir,x+".part")));
}
Enumeration en=Collections.enumeration(list);
SequenceInputStream sis=new SequenceInputStream(en);
File dir=new File(“c:\partfiles”);
FileOutputStream fos=new FileOutputStream(new File(dir,".bmp"));
byte[] buf=new byte[024];
int len=0;
while((len=sis.read(buf))=-1)
{
fos.write(buf,0,len);

}
fos.close();
sis.close();
文件切割和合并的专业做法:切割文件时候,必须记录切割文件的名称,以及切割出文件锁片的个数,以方便于合并
(四)对象流
1、对象流的概念:
(1)、对象序列化 (Serialization)
将Java对象转换成字节序列(IO字节流)
(2)、对象反序列化 (DeSerialization)
从字节序列中恢复Java对象
2、为什么序列化
序列化以后的对象可以保存到磁盘上,也可以在网络上传输,使得不同的计算机可以共享对象.(序列化的字节序列是平台无关的)
3、对象序列化的条件
只有实现了Serializable接口的类的对象才可以被序列化。Serializable接口中没有任何的方法,实现该接口的类不需要实现额外的方法
如果对象的属性是对象,属性对应类也必须实现Serializable接口
ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectInputStream 用于恢复那些以前序列化的对象。其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参
【1】对象序列化的例子
public class Test {
public static void writeObj() throws Exception{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(“e:\aaa.txt”));
//对象被序列化,被序列化的对象必须实现Serializable接口
oos.writeObject(new Person(“zhangsan”,21));
oos.close();
}
public static void main(String[] args) throws Exception {
Test.writeObj();
}
}
class Person implements Serializable{
private String name;

public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
}

【2】对象反序列化的例子
public class Test {
public static void writeObj() throws Exception{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(“e:\aaa.txt”));
//对象被序列化,被序列化的对象必须实现Serializable接口
oos.writeObject(new Person(“zhangsan”,21));
oos.close();
}
public static void readObj() throws Exception{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(“e:\aaa.txt”));
Person p=(Person)ois.readObject();
System.out.println(p.getName()+"====="+p.getAge());
ois.close();
}
public static void main(String[] args) throws Exception {
Test.readObj();
}
}
注意:
(1)序列化只能保存对象的非静态成员变量;不能保存任何成员方法和静态的成员变量;不保存transient成员变量;如果一个对象的成员变量是一个对象,这个对象的成员变量也会保存;串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。使用对象流把一个对象写到文件时不仅保证该对象是序列化的,而且该对象的成员对象也必须是可序列化的
(2)如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化
(3)同一个对象多次序列化的处理
3.1所有保存到磁盘中的对象都有一个序列化编号
3.2序列化一个对象中,首先检查该对象是否已经序列化过,如果没有,进行序列化;
如果已经序列化,将不再重新序列化,而是输出编号即可
3.3如果不希望某些属性(敏感)序列化,或不希望出现递归序列,为属性添加transient关键字(完成排除在序列化之外)自定义序列化(不仅可以决定哪些属性不参与序列化,还可以定义属性具体如何序列化)
3.4序列化版本不兼容,修改了实例属性后,会影响版本号,从而导致反序列化不成功
解决方案:为Java对象指定序列化版本号serialVersionUID
(五)Java的其它IO流简介
1、DataInputStream和DataOutputStream
DataInputStream和DataOutputStream提供了可以存取所有Java基础类型数据(如:int,double 等)和String的方法。它是一个处理流,只针对字节流,二进制文件
在这里插入图片描述
2、字节/字符数组/字符串流
(1)字节流:ByteArrayInutStream和ByteArrayOutputStream
数据源或目的地为:字节数组。只有字节流,没有字符流
(2)字符数组:CharArrayReader和CharArrayWriter
数据源或目的地为:字符数组。只有字符流,没有字节流
(3)字符串流:StringReader和StringWriter
数据源或目的地为:字符串。只有字符流,没有字节流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值