java基础--IO流之其它流对象
来源:互联网 发布:美工的岗位职责 编辑:程序博客网 时间:2024/04/30 04:45
笔记摘要:
本篇文章主要是对于IO流中除了经常见到的读写流之外的一些其他流对象,有
Properties、打印流、合并流SequenceInputStream、对象的序列化,持久化的流对象、
管道流对象、操作基本数据类型的流对象、 随机访问文件流对象以及源和目的都是内存的IO流对象
一、Properties
Properties是hashtable的子类。
也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:
可以用于键值对形式的配置文件。
那么在加载数据时,需要数据有固定格式:键 = 值。
Properties练习:记录应用程序运行次数,如果使用次数已到,那么给出注册提示
示例说明:
该配置文件使用键值对的形式,这样便于阅读数据,并操作数据。
键值对数据是map集合,数据是以文件形式存储,使用io技术。
那么map+io-->properties.
配置文件可以实现应用程序数据的共享。
程序中发现的问题:
FileOutputStream的创建应该在count自加之后,这样每次创建FileOutputStream时,就可以用新值覆盖旧值。如果在之前创建,需要将boolean值设为true,这样count才不会被覆盖,否则,文件被覆盖,count获取到的值为null,那么count的值在+1后,第二次会重复这样的操作,所以永远是1,这样就会在文件后面写入,所以出现多条除了count其它都相同的信息,所以我们在count+1后再创建FileOutputStream,让它去覆盖
package cn.xushuai.io;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;public class RunCount {public static void main(String[] args) throws IOException {File file = new File("c:\\info.ini");if(!file.exists())try {file.createNewFile();} catch (IOException e) {throw new RuntimeException("创建文件失败");}int count =0;Properties prop = new Properties();FileInputStream fis = new FileInputStream(file);//在这里定义输出流,由于没有设为true,所以每次会覆盖源文件,//所以count只能在本次运行后+1,之后又被覆盖,所以总是1。//FileOutputStream fos = new FileOutputStream(file);try {prop.load(fis);String value = prop.getProperty("time");if(!(value == null))count = Integer.parseInt(value);if(count>5){System.out.println("试用期限已到,请到官网注册!");return ;}count++;//在count自增过后再创建,然后将count的新值覆盖旧值FileOutputStream fos = new FileOutputStream(file);prop.setProperty("time", count+"");prop.store(fos, "");} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
二、 打印流
该流提供了打印方法,可以将各种数据类型的数据都原样打印
字节打印流:PrintStream
字符打印流:PrintWriter
字节打印流PrintStream构造函数可以接收的参数类型
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流PrintWriter构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer
PrintWriter可以同时传入输出流对象和boolean值,以便实现自动刷
import java.io.*;class PrintStreamDemo{public static void main(String[] args) throws IOException{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);PrintWriter out2 = new PrintWriter(System.out,true);//打印到控制台,并自动刷新String line = null;while((line=bufr.readLine())!=null){if("over".equals(line))break;out2.println(line.toUpperCase());//out.flush();}out2.close();bufr.close();}}
三、 合并流SequenceInputStream
使用说明:
操作合并流的时候需要将操作的文件读取流封装成对象,存入集合中,然后进行写入,又因为SequenceInputStream接收一个Enumeration 类型的参数,而枚举类型只有在Vector中才有,所以只能使用Vector集合,通过elements方法获取枚举,传入SequenceInputStream。然后确定写入流,进行读写。
由于Vector效率低,所以用ArrayList替代,但要想得到枚举类型,可以利用迭代器,创建Enumeration对象,通过匿名内部类的方法实现Enumeration接口,并使用迭代器的方法覆盖其中的hasMoreElements和nextElement方法,然后确定写入流,进行读写。
文件的切割与合并示例代码:
import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.SequenceInputStream;import java.util.ArrayList;import java.util.Enumeration;import java.util.Iterator;public class SplitFileDemo {public static void main(String[] args) throws IOException {// TODO Auto-generated method stub//splitFile();merge();}public static void splitFile() throws IOException {FileInputStream fis = new FileInputStream("c:\\1.mp3");FileOutputStream fos = null;byte[] buf = new byte[1024*1024];int len = 0;int count=1;while((len = fis.read(buf))!=-1){fos = new FileOutputStream("c:\\"+(count++)+".part");fos.write(buf,0,len);fos.close();}/*//应该让程序自动运行,而不是手动指定要切割多少次for(int i=1;i<13;i++){//FileOutputStream fos = new FileOutputStream("c:\\"+i+".part");while((len = fis.read(buf))!=-1){ fos = new FileOutputStream("c:\\"+(count++)+".part");//应该在外部定义,避免创建不需要的对象//FileOutputStream fos = new FileOutputStream("c:\\"+(count++)+".part");fos.write(buf,0,len);fos.close();System.out.println("......"+count);}}*/fis.close();}public static void merge() throws IOException{ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();for(int i=0;i<12;i++){al.add(new FileInputStream("c:\\"+i+".part"));}//通过Iterator来获取枚举方法final Iterator<FileInputStream> it = al.iterator();//通过内部类的形式来创建枚举Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {@Overridepublic boolean hasMoreElements() {//使用迭代器的方法来覆盖枚举的方法return it.hasNext();}@Overridepublic FileInputStream nextElement() {return it.next();}};SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("c:\\merge.mp3");int len=0;byte[] buf = new byte[1024];while((len=sis.read(buf))!=-1){fos.write(buf,0,len);}sis.close();fos.close();}}
四、对象的序列化,持久化对象
ObjectInputStream
ObjectOutputStream
可以直接将对象持久的存入介质中,并读出,必须成对使用。
使用注意事项:
1>进行序列化时需要继承Serializable, 以启用其序列化功能。(该序列化只能将堆内存中的数据序列化,序列号是根据类中的成员计算而得)
2>由于定义的类后期可能会进行修改,因此重新编译后会生成新的序列号,为了让原有类被序列化的数据可以继续使用,必须给类进行自定义标识,
该标识必须是静态,最终,长整型的 :static final long serialVersionUID = 42L;
3>静态不能够序列化,由于对象是在对内存中的。
4>对非静态成员也不想序列化,可以用transient修饰,保证其值在堆内存中存在而不在文本文件中存在。
示例代码:
import java.io.*;class Person implements Serializable{public static final long serialVersionUID = 42L;private String name;transient int age;static String country = "cn";Person(String name,int age,String country){this.name = name;this.age = age;this.country = country;}public String toString(){return name+":"+age+":"+country;}}import java.io.*;class ObjectStreamDemo {public static void main(String[] args) throws Exception{//writeObj();readObj();}public static void readObj()throws Exception{ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));Person p = (Person)ois.readObject();System.out.println(p);ois.close();}public static void writeObj()throws IOException{ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));oos.writeObject(new Person("lisi0",399,"kr"));oos.close();}}
五、管道流
PipedInputStreamPipedReader
PipedOutputStream PipedWriter
可以直接将输入流与输出流连接,将流中的数据直接写入到读取端,必须结合多线程使用,因为单线程可能导致死锁。
管道流使用示例代码:
import java.io.*;class Read implements Runnable{private PipedInputStream in;Read(PipedInputStream in){this.in = in;}public void run(){try{byte[] buf = new byte[1024];System.out.println("读取前。。没有数据阻塞");int len = in.read(buf);System.out.println("读到数据。。阻塞结束");String s= new String(buf,0,len);System.out.println(s);in.close();}catch (IOException e){throw new RuntimeException("管道读取流失败");}}}class Write implements Runnable{private PipedOutputStream out;Write(PipedOutputStream out){this.out = out;}public void run(){try{System.out.println("开始写入数据,等待6秒后。");Thread.sleep(6000);out.write("piped lai la".getBytes());out.close();}catch (Exception e){throw new RuntimeException("管道输出流失败");}}}class PipedStreamDemo{public static void main(String[] args) throws IOException{PipedInputStream in = new PipedInputStream();PipedOutputStream out = new PipedOutputStream();in.connect(out);Read r = new Read(in);Write w = new Write(out);new Thread(r).start();new Thread(w).start();}}
六、操作基本数据类型的流对象
DataInputStream
DataOutputStream
直接对基本数据类型进行操作,由于存入数据的类型可能不一致,所以读取时应注意顺序的一致,否则出现乱码
示例代码
import java.io.*;class DataStreamDemo {public static void main(String[] args) throws IOException{//writeData();//readData();//writeUTFDemo();//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");////osw.write("你好");//osw.close();//readUTFDemo();}public static void writeData()throws IOException{DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));dos.writeInt(234);dos.writeBoolean(true);dos.writeDouble(9887.543);dos.close();ObjectOutputStream oos = null;oos.writeObject(new O());}public static void readData()throws IOException{DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));int num = dis.readInt();boolean b = dis.readBoolean();double d = dis.readDouble();System.out.println("num="+num);System.out.println("b="+b);System.out.println("d="+d);dis.close();}//使用修改版的UTF-8写入,必须用相应的方式读取,用转换流读不出来public static void writeUTFDemo()throws IOException{DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));dos.writeUTF("你好");dos.close();}public static void readUTFDemo()throws IOException{DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));String s = dis.readUTF();System.out.println(s);dis.close();}}
七、RandomAccessFile
随机访问文件,自身具备读写的功能,只能操作文件。
使用说明:
1>通过skipBytes(intx) ,seek(int x)来达到随机访问
2>该类不是IO中的子类,而是直接继承自Object,但是它是IO包中的成员,因为它 具备读和写的功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,其完成读写的原理就是内部封装了字节输入流和输出流、
3>该类只能操作文件,而且还有操作模式,
如果模式为只读 r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw,操作的文件不存在,会自动创建,如果存则不会覆盖。
4>该类可以利用多线程实现分段写入,文件的下载就是此原理。
随机读取示例:
class RandomAccessFileDemo {public static void main(String[] args) throws IOException{//writeFile_2();//readFile();//System.out.println(Integer.toBinaryString(258));}//写入数据,同时移动指针public static void writeFile()throws IOException{RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");raf.write("李四".getBytes());raf.writeInt(97);raf.write("王五".getBytes());raf.writeInt(99);raf.close();}//可以任意修改数据public static void writeFile_2()throws IOException{RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");raf.seek(8*0);raf.write("周期".getBytes());raf.writeInt(103);raf.close();}//可以任意读取数据public static void readFile()throws IOException{RandomAccessFile raf = new RandomAccessFile("ran.txt","r");//调整对象中指针。//raf.seek(8*1);//跳过指定的字节数raf.skipBytes(8);byte[] buf = new byte[4];raf.read(buf);String name = new String(buf);int age = raf.readInt();System.out.println("name="+name);System.out.println("age="+age);raf.close();}}
八、源和目的都是内存的IO类
用流的读写思想来操作数据
操作字节数组 ByteArrayInputStream ByteArrayOutputStream
字符数组 CharArrayReader CharArrayWrite
字符串 StingReader StringWriter
ByteArrayInputStream :
在构造的时候,需要接收数据源,而且数据源是一个字节数组
ByteArrayOutputStream:
在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地。
注意:
因为这两个流对象都操作的数组,并没有使用系统资源, 所以,不用进行close关闭。
import java.io.*;class ByteArrayStream {public static void main(String[] args) {//数据源。ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());//数据目的ByteArrayOutputStream bos = new ByteArrayOutputStream();int by = 0;while((by=bis.read())!=-1){bos.write(by);}System.out.println(bos.size());System.out.println(bos.toString());//一次性地将数据写入文件//bos.writeTo(new FileOutputStream("a.txt"));}}
- java基础--IO流之其它流对象
- java基础学习IO流之其它流 十一 -6
- Java基础-IO-其它流(笔记)
- java基础--IO流中的其它流和其它类
- 黑马程序员_JavaSE基础20 之 其它对象API IO流 FileReader FileWriter合
- JAVA基础复习二十二-IO流-其它流
- Java基础--- 其它对象
- java基础5:io流对象之字节输入输出流
- java基础6:io流对象之字符输入输出流
- java基础7:io流对象之转换流
- java基础8:io流对象之缓冲流
- Java基础<十六>---> IO之其他流对象
- java基础之IO流--ObjectOutputStream(专门用于操作对象)
- 黑马程序员--IO中的其它流对象
- 黑马程序员----Java基础之IO包中其它类
- java基础之IO流--DataOutputStream(专门用于操作Java基本数据类型的IO流对象)
- java基础之 IO流
- Java基础之IO流
- Android系统手机端抓包方法
- 内部类
- Linux下安装ruby
- Oracle 多表视图更新
- HR 系统系列:简介
- java基础--IO流之其它流对象
- mongoDB 管理
- 通用标签小结一
- php 简单数组问题
- shell编程之一---调试
- Android中调用系统所装的软件打开文件
- WIN8系统的远程桌面漏洞 利用QQ拼音纯净版实现提权
- linux iostat命令详解
- 我们要完成哪些“软件”的更新——找出可能导致失败的根源