IO流的打印流、序列流其他流总结


1、打印流:就是输出流,可以直接操作输入流和文件

printStream:字节流

特点:1、构造函数接收File对象、字符路径、字符输出流

  2、该对象具有特有的方法,print println可以打印任何数据类型的数据。

  3、特有的printf方法可以保持任意类型的数据表现形式的原样性,将数据输出到目的地,对于OutputStream父类中的write是将数据的最低字节写出去、

API:为其他的输出流添加了功能,使他们能够方法便的打印各种数据值表示形式,它还提供了其他两项功能。与其他输出流不同,printStream永远不会抛出IOException异常,而是异常情况仅设置可通过checkError方法测试的内部标识,另外,为了自动刷新,可以创建一个printStream,这以为着可在写入byte数组之后自动调用flush方法,可吊桶其中一个println方法,或者写入一个换行符或者字节(\r\n),printStream打印的所有字符都使用平台默认字符编码转换为字节,在需要写入字符而不是写入字节的情况下,应该使用printWriter类。

注意:能写一个整数、还能打印一个整数为什么?

Write(97);a

0000-0000  0000-0000 0000-0000 0110-0001 97

将最后一个八位写入到硬盘,也就是最后一个字节0110-0001记事本把这个二进制解析了,然后查表返回a;

Print(97);你看到是什么?目的里面就是什么?97

原理:先把97--->"97"--->"97".getBytes()(2个字节)

 

printWriter字符流:使用频繁,因为需要将数据从服务端打印到客户端

特点:

1、当操作的数据是字符时,可以选择printWriter比printStream更方便。

2、它的构造函数可以接收File对象,字符串路径、字节输出流、字符流。

3、可以在构造函数中、如果参数是输出流,那么可以通过指定另一个参数true来完成自动刷新,该方法只对println()有效。

实现代码:

BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

PrintWriter out=new PrintWriter(new BufferedWriter( new FileWriter("out.txt")),true);

//加上true它能自动刷新,但是只能对println有效,需要高效,而且具备自动刷新的功能的只有字符流和字节流,所以需要封装为字符输出流。

String line=null;

while((line=buf,.readLine())!=null){

If("over".equals(line))

break;

}

out.println(line);

out.close();

//什么时候用?当需要保证数据表现的原样性时,就可以使用打印流的打印方法来完成,保证(表现形式)原样性的原理:其实就是将数据变成字符串,再进行写入操作。

 

2、序列流:按照一定顺序排列。

SequenceInputStream:对多个流进行合并。作用:将多个字节读取流合并成一个读取流。

特点:

1、将多个自己流合并成一个读取流,将多个源合并成一个源,操作起来方便。

2、需要的枚举接口可以通过collections.enumeration(collection);

练习:切割照片

注意:切割有两种方式:1、按照大小,2、按照文件个数。

3、操作对象:

将对象写入设备的方式,称为对象的持久化存储。

ObjectInputStream ObjectOutputStream

实现代码:

public staticvoid main(String[] args){

writeObj();

readObj();

}

Public staticvoid readObj(){

FileInputStream fis=new FileInputStream("obj.txt");

ObjectInputStream ois=new ObjectInputStream(fis);

Person p=(Person)ois.readObject();

Sysotem.out.println(p.getAge()+p.getName());

ois.close();

}

Public staticvoid writeObj(){

FilleOutputStream fos=new FileOutputStream("obj.txt");

Person p=new Person("wangwu",34);

ObjectOutputStream oos=new ObjectOutputStream(fos);

oos.writeObject(p);

fos.close();

}

给需要序列化的类打个标记,seriablizeble接口

注意:

框架和面试的时候常面到,比如对象的声明周期的延长,以前是内存,现在存储到硬盘中,静态数据不会被序列化,

eg:private static String name,静态之后读取的是34,null;因为静态之后name存储到了方法区,写到硬盘中与它无关。

Transient:可以让非静态的数据不被序列化。

细节:

1、用ObjectOutputStream写出的数据只能用ObjectInputStream读取。

2、文件存储的是对象的时候,使用object来表示扩展名的。

4、RandomAccessFile:随进访问文件,此类的实例支持对随进访问的文件读和写。

特点:

1、可以读取又可以写入
2、内部维护了一个大型的byte数组,通过对数组的操作完成读取和写入

3、通过getFilePointer方法获取指针的位置,还可以通过seek方法获取指针的位置。

4、该对象内容应该封装了字节输入流和字节输出流。

5、该对象只能操作文件。

实现代码:

 

public classRandomAccessFileDemo {

       public static void main(String[] args)throws IOException {

              randomWrite();

       }

       /*

        * 随机写入。

        */

       public static void randomWrite()throwsIOException{

              RandomAccessFileraf = new RandomAccessFile("random.txt", "rw");

              int num = 0;

             

              raf.seek(8*num);

              /*

               * 写入信息。

               */

              raf.write("张三".getBytes());

              raf.writeInt(65);

             

              raf.close();

             

       }

      

       /*

        * 随机读取。

        */

       public static void randomRead() throwsIOException{

             

              //读取信息

              RandomAccessFile raf = new RandomAccessFile("random.txt", "r");

             

              int n = 1;

              //只要改变指针的位置,通过seek方法。

              raf.seek(8*n);

             

              byte[] buf = new byte[4];

              raf.read(buf);//一次读四个字节并存储。

             

              String name = new String(buf);

             

              int age = raf.readInt();

             

              System.out.println(name+".."+age);

             

              System.out.println("pos:"+raf.getFilePointer());

             

              raf.close();

             

       }

      

       /*

        * 读取数据。random.txt 使用RandomAccessFile.

        */

       public static void readFile() throwsIOException{

              RandomAccessFile raf = new RandomAccessFile("random.txt","r");

             

              byte[] buf = new byte[4];

              raf.read(buf);//一次读四个字节并存储。

             

              String name = new String(buf);

             

              int age = raf.readInt();

             

              System.out.println(name+".."+age);

             

             

              raf.close();

             

       }

      

       /*

        * 通过RandomAccessFile类创建文件并给文件中写入数据。

        * 数据以:姓名+年龄为主的个人信息。

        */

       public static void writeFile() throwsIOException{

             

              /*

               * 创建RandomAccessFile对象时,如果文件不存在则创建,

               * 如果文件已存在,则不创建。

               */

              RandomAccessFile raf = new RandomAccessFile("random.txt","rw");

             

              raf.write("张三".getBytes());

              raf.writeInt(97);

              raf.write("李四".getBytes());

              raf.writeInt(99);

             

              raf.close();

             

       }

 

}

通过seek方法操作指针,可以从这个数组中任意位置上进行读和写,还可以完成数据的修改,但是要注意数据必须是有规律的。

5、管道流:需要多线程技术相结合的流对象。

PipedInputStream和PipedOutputStream

可以将管道输出流连接到管道输入流来创建通信管道。

Read方法有一个特点:阻塞,没数据的时候在等待,不往下执行

Eg:

-->write--->read:能正常执行

-->read---->write:这就会出现死锁。所以管道流需要和多线程技术相结合的流

有两个方式进行连接:1、构造函数,已初始化就明确,2、connect();方法。

实现代码:

public static void main(String[] args) throws IOException {

 

              PipedInputStream pis = new PipedInputStream();

              PipedOutputStream pos = new PipedOutputStream();

              pis.connect(pos);

             

              newThread(new MyRead(pis)).start();

              newThread(new MyWrite(pos)).start();

             

             

       }

 

}

 

class MyRead implements Runnable{

       private PipedInputStream pis;

      

       public MyRead(PipedInputStream pis) {

              super();

              this.pis= pis;

       }

 

       public void run(){

              try{

                     byte[] buf = new byte[1024];

                    

                     System.out.println("正在读取中。。。。。。。");

                     int len = pis.read(buf);

                    

                     String str = new String(buf,0,len);

                     System.out.println("str="+str);

                    

                     pis.close();

              }catch (Exception e) {

                    

              }

       }

}

class MyWriteimplements Runnable{

       private PipedOutputStream pos;

      

       public MyWrite(PipedOutputStream pos) {

              super();

              this.pos= pos;

       }

 

       public void run(){

              try{

                     System.out.println("数据准备写入。。。。。。。。");

                     Thread.sleep(5000);

                     pos.write("管道流,我来了!".getBytes());

                    

                     pos.close();

              }catch (Exception e) {

              

              }

       }

}

 

6、IO包中其他的类

1、操作基本数据类型DataInputStream和DataOutputStream用于操作基本是的数据类型值的对象。

实现代码:

public staticvoid main(Strijng[] args){

readData();

}

public staticvoid writeData(){

DataOutputStream dos=new DataOutputStream(newFileOutoutStream("data.txt"));

dos.writeBoolean(true);

dos.close();

}

public staticvoid readData(){

DataInputStream dis=new DataInputStream(newFileInputStream("data.txt"));

Boolean b=dis.readBoolean();

Sysotem.out.println(b);

 

Dis.close();

}

    2、ByteArrayInputStream 和ByteArrayOutStream

        操作字节数组的。其实就是操作内存设备的流对象。

        ByteArrayOutStream:

        此类实现了一个输出流,其中数据被写入到一个byte数组,缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

        关闭是无效的,为什么?因为此类并没有调用低层的资源,而是直接在操作内存中的数组。

        ByteArrayInputStream:

        包含一个内部缓冲区,该缓冲区包含从流中读取的字节,关闭也是无效的,一初始化必须有数据。该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。 关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

         实现代码:

        //源是内存,目的也是内存,用的就是流的读写思想来操作数组。

        ByteArrayInputStream bis=new ByteArrayInputStream("abcds".getBytes());

        ByteArrayOutputStream bos=new ByteArrayOutputStream();

        int ch=0;

        while((ch=bis.read())!=-1){

            bos.write(ch);

        }


你可能感兴趣的:(IO流的打印流、序列流其他流总结)