IO流知识点总结02



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-00000110-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(newInputStreamReader(System.in));

PrintWriter out=new PrintWriter(newBufferedWriter( 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 static void main(String[] args){

writeObj();

readObj();s

}

Public static void readObj(){

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

ObjectInputStream ois=newObjectInputStream(fis);

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

Sop(p.getAge()+p.getName());

Ois.close();

}

Public static void writeObj(){

FilleOutputStream fos=newFileOutputStream("obj.txt");

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

ObjectOutputStream oos=newObjectOutputStream(fos);

oos.writeObject(p);

Oos.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、该对象只能操作文件。

实现代码:

package cn.itcast.f.io.random_access.demo;

 

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.RandomAccessFile;

 

public class RandomAccessFileDemo {

 

       /**

       * @param args

       * @throws IOException

       */

       publicstatic void main(String[] args) throws IOException {

 

//           writeFile();

//           randomRead();

             randomWrite();

       }

       /*

       * 随机写入。

       */

       publicstatic void randomWrite()throws IOException{

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

            

             int num = 0;

            

             raf.seek(8*num);

             /*

              * 写入第四个人的信息。王五 102.

              */

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

             raf.writeInt(65);

            

             raf.close();

            

       }

      

       /*

       * 随机读取。

       */

       publicstatic void randomRead() throws IOException{

            

             //读取任意一个人的信息,比如李四。

             RandomAccessFile raf = newRandomAccessFile("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.

       */

       publicstatic void readFile() throws IOException{

             RandomAccessFile raf = newRandomAccessFile("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类创建文件并给文件中写入数据。

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

       */

       publicstatic void writeFile() throws IOException{

            

             /*

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

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

              */

             RandomAccessFile raf = newRandomAccessFile("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 = newPipedInputStream();

             PipedOutputStream pos = new PipedOutputStream();

             pis.connect(pos);

            

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

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

            

            

       }

 

}

 

class MyRead implements Runnable{

      private PipedInputStream pis;

      

       publicMyRead(PipedInputStream pis) {

             super();

             this.pis = pis;

       }

 

       publicvoid run(){

             try {

                   byte[] buf = new byte[1024];

                   

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

                    intlen = pis.read(buf);

                   

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

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

                   

                   pis.close();

             } catch (Exception e) {

                    //TODO: handle exception

             }

       }

}

class MyWrite implements Runnable{

      private PipedOutputStream pos;

      

       publicMyWrite(PipedOutputStream pos) {

             super();

             this.pos = pos;

       }

 

       publicvoid run(){

             try {

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

                   Thread.sleep(5000);

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

                   

                   pos.close();

             } catch (Exception e) {

                    //TODO: handle exception

             }

       }

}

 

6、IO包中其他的类

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

实现代码:

Public static void main(Strijng[] args){

readData();

}

Public static void writeData(){

DataOutputStream dos=newDataOutputStream(new FileOutoutStream("data.txt"));

dos.writeBoolean(true);

Dos.close();

}

Public static void readData(){

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

//Int ch=dis.read();

//Sop(ch);得按照基本数据类型来读取

Boolean b=dis.readBoolean();

Sop(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);

 }

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值