java笔记26 IO流其他对象

1.       打印流

PrintWriter与PrintStream:可以直接操作输入流和文件。

PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

与其他输出流不同,PrintStream永远不会抛出IOException。

PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。

在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类。

字节打印流

         PrintStream

    构造函数可以接受的函数类型

     1、file对象

     2、字符串路径   String

     3、字节输出流 OutputStream  

字符打印流

         PrintWriter

         构造函数可以接受的函数类型    

1、file对象

    2、字符串路径   String

3、字节输出流 OutputStream

4、字符输出流  Writer

         示例       

import java.io.*;

public class H_15PrintDemo {

    public static void main(String[] argsthrows IOException

    {

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

        PrintWriter out=new PrintWriter(System.out);

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

        //直接传入true 可以自刷新   不能刷新到文件 将文件封装成流对象

        String line=null;

        while((line=bufr.readLine())!=null)

        {

            if("over".equals(line))

                break;

            out.println(line.toLowerCase());       

            out.flush();//不刷新会再关闭后一起打印

        }

        out.close();

        bufr.close();

    }

}


 

2.       合并流SequenceInputStream

import java.util.*;

import java.io.*;

public class H_16SequenceInputStream {

 

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

        Vector<FileInputStream> v=new Vector<FileInputStream>();//创建一个集合,添加文件

        v.add(new FileInputStream("info.txt"));

        v.add(new FileInputStream("java.txt"));

        v.add(new FileInputStream("buf.txt"));

        Enumeration<FileInputStream> en=v.elements();

        SequenceInputStream sis=new SequenceInputStream(en);//传入一个枚举对象

        FileOutputStream fos=new FileOutputStream("seq.txt");//合并的文件

        byte[] buf=new byte[1024];

        int len=0;

        while((len=sis.read(buf))!=-1)

        {

            fos.write(buf, 0, len);

        }

        fos.close();

        sis.close();       

    }

}


3.       切割函数与高效合并

public static void splitFile() throws IOException

    {

        FileInputStream fis=new FileInputStream("TBBT_copy2.png");

        FileOutputStream fos=null;

        byte[] buf=new byte[1024*1024];//设置文件大小

        int len=0;

        int count=1;

        while((len=fis.read(buf))!=-1)

        {

            fos=new FileOutputStream((count++)+".part");//按大小切割文件

            fos.write(buf, 0, len);

            fos.close();

        }      

        fis.close();

    }

    public static void merge() throws IOException

    {

        ArrayList<FileInputStream> al=new ArrayList<FileInputStream>();

        for(int x=1;x<=3;x++)

        {

            al.add(new FileInputStream(x+".part"));        

        }

        final Iterator<FileInputStream> it=al.iterator();

        Enumeration<FileInputStream> en=new Enumeration<FileInputStream>()//数组集合要用枚举,必须使用内部类重写方法

                {

                    public boolean hasMoreElements() {

                            return it.hasNext();

                    }

                    public FileInputStream nextElement() {

                            return it.next();

                    }                  

                }; 

//Enumeration<FileInputStream> en = Collections.enumeration(al);

//也可以使用Collections的方法

        SequenceInputStream sis=new SequenceInputStream(en);

        BufferedOutputStream bos=new BufferedOutputStream(newFileOutputStream("copy.png"));

        byte[] buf=new byte[1024];

        int len=0;

        while((len=sis.read(buf))!=-1)

        {

            bos.write(buf, 0, len);

            bos.flush();

        }      

        bos.close();

        sis.close();       

    }

}

 

4.       序列化流 ObjectOutputStream

1、序列化  即存储起来  不会因为程序消亡而消亡

2、成员必须实现序列化类Serializable才可以进行序列化

静态成员是不能被序列化的

非静态成员不想被序列化的话,加上transient int age//临时的  中转的意思    

         通常保存成  类名.类型名

3、如果第一次序列化后,

         如果改变Person 成员属性  uid 会改变

         再次读取原编译文件会报错,因为uid不同。         

4、自定义uid

         static final long serialVersionUID=42L

         那么序列号都相同,修改后也不会报错。

import java.io.*;

public class H_01ObjectOutputStream {

    public static void main(String[] argsthrows IOException, ClassNotFoundException {

        writeObj();//序列化后的文件是看不懂的

        readObj();     

    }

    public static void readObj() throws IOException, ClassNotFoundException

    {

        ObjectInputStream ois=new ObjectInputStream(newFileInputStream("obj.txt"));

        //通常命名为obj.object,此处做演示打开看看

        Object obj=ois.readObject();

        System.out.print(obj);

        ois.close();

    }

    public static void writeObj() throws IOException

    {

        ObjectOutputStream oos=new ObjectOutputStream(newFileOutputStream("obj.txt"));

        oos.writeObject(new Person("lisi",39));    

        oos.close();

    }  

}

class Person implements Serializable //可序列化的 ,该接口没有方法  仅仅是标记

{

    String name;

    int age;

    Person(String name,int age)

    {

        this.name=name;

        this.age=age;

    }

    public String toString()

    {

        return name+"  "+age;

    }  

}

 

5.       管道流

         集合涉及多线程:Properties

        流对象涉及多线程:管道流

        创建需要多线程的读方法和写方法。

 read中构造函数传入读取管道流

 write中构造函数传入写入管道流

                    分别重写run方法及读取方法和写入方法。      

        主函数

        new 管道读取流和管道写入流对象

        需要建立关联 in.connect(out);

        分别传入read和write构造函数

        新建线程对象,传入read和write对象

import java.io.*;

public class H_02PipeInputStream {

    public static void main(String[] argsthrows IOException

    {

        PipedInputStream in=new PipedInputStream();

        PipedOutputStream out=new PipedOutputStream();

        in.connect(out);//关联

        Read read=new Read(in);//传入对象

        Write write=new Write(out);

        new Thread(read).start();//启动线程

        new Thread(write).start();

    }

}

 

class Read implements Runnable

{

    private PipedInputStream in;

    Read(PipedInputStream in)

    {

        this.in=in;

    }

    public void run()

    {

        try {

            byte[] buf=new byte[1024];

            int len=in.read(buf);

            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 {

            Thread.sleep(3000);

            out.write("piped ce shi ".getBytes());

            out.close();

        } catch (Exception e)

        {

            throw new RuntimeException("管道流写入失败");

        }

    }

}


6.       随机访问文件

1、 RandomAccessFile

        该类不算是IO体系中的子类,而是直接继承自Object。但是它是IO体系的成员,具备读写功能。

        内部封装了一个数组,通过指针对数组的元素进行操作。

        可以通过getFilePointer获取指针位置

        同时可以通过seek改变指针的位置

        读写的原理是内部封装了字节输入流和输出流

2、 通过构造函数可以看出:该类只能操作文件

        而且后面有四种模式   r  rw  rws  rwd   输错会报参数错误异常

                   如果模式为只读r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常

                   如果模式rw,操作的文件不存在,会自动创建,如果存在,则不会覆盖。

3、 raf.write(259);//只能写入最低八位,会导致数据丢失

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

                   //调整对象上的指针

         raf.seek(10);//按字节数来获取  从第十个直接开始         

                   //跳过指定的字节数

         raf.skipBytes(4);//跳过四个字节    但是不能往前跳       

         作用:  实现数据的分段写入

                            将数据分段:用不同的线程负责不同段的写入

         应用:程序的分段下载

4、 重点特点:

                   有模式限制

                   seek设置读取位置

                   可以直接操作基本数据类型

import java.io.*;

public class H_03RandomAccessFile {

    public static void main(String[] argsthrows IOException {

        //writeFile();     

        writeFile_2();

        readFile();

    }

    public static void readFile() throws IOException

    {

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

        //调整对象上的指针

        //raf.seek(10);//按字节数来获取  从第十个直接开始    

        //跳过指定的字节数

        raf.skipBytes(4);//跳过四个字节    但是不能往前跳    

        byte[] buf=new byte[4];

        raf.read(buf);

        String s=new String(buf);

        System.out.println(s);     

        int age=raf.readInt();

        System.out.println(age);

        raf.close();       

    }

    public static void writeFile_2() throws IOException

    {

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

        raf.write("lisi".getBytes());

        raf.writeInt(97);

        raf.seek(8*4);//跳过四个8位写入

        raf.write("zhangsan".getBytes());

        raf.close();       

    }

    public static void writeFile() throws IOException

    {

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

        raf.write("lisi".getBytes());

        raf.write(7);//只能写入最低八位,会导致数据丢失

        raf.writeInt(3);//写入四位,前面是空格

        raf.write("haha".getBytes());

        raf.close();       

    }

}


7.       数据流DataInputStream DataOutputStream        

        可以用于操作基本数据类型

        直接读或者取整数、小数、布尔值等等。

        特殊方法  writeUTF   readUTF

        修改版的utf编码

                 写入两个汉字是 8字节

                 utf正常是6字节

                 gbk是4字节

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStreamWriter;

 

public class H_04DataStreamDemo {

    public static void main(String[] argsthrows IOException {

        // TODO Auto-generated method stub

        //writeData();

        //readData();

        writeUTFDemo();

        readUTFDemo();

        OutputStreamWriter osw=new OutputStreamWriter(newFileOutputStream("GBK.txt"));

        osw.write("你好");

        osw.close();

    }

    public static void readUTFDemo() throws IOException

    {

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

        String s=dis.readUTF();

        System.out.println(s);

    }

    public static void writeUTFDemo() throws IOException

    {

        DataOutputStream dos=new DataOutputStream(newFileOutputStream("utfdata.txt"));

        dos.writeUTF("你好");

        dos.close();

    }

    public static void readData() throws IOException

    {

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

        //必须按照写入的顺序读取

        int num=dis.readInt();

        double dou=dis.readDouble();

        boolean bool=dis.readBoolean();

        System.out.println(num);

        System.out.println(dou);

        System.out.println(bool);

    }

    public static void writeData() throws IOException

    {

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

        dos.writeInt(333);

        dos.writeDouble(988989.34343);

        dos.writeBoolean(true);   

        dos.close();

    }

}


8.       操作字节数组流

 ByteArrayInputStream与ByteArrayOutputStream

         ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组

        ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组

        因为这两个流对象都操作字节数组,并没有使用系统资源,所以不用close关闭,也不会报IO异常

import java.io.*;

public class H_05ByteArrayStream {

    public static void main(String[] argsthrows IOException{      

        //数据源

        ByteArrayInputStream bis=newByteArrayInputStream("abcedef".getBytes());     //数据目的

        ByteArrayOutputStream bos=new ByteArrayOutputStream();     

        int ch=0;

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

        {

            bos.write((char)ch);      

        }

        System.out.println(bos.size());//7

        System.out.println(bos.toString().toUpperCase());//ABCEDEF

        bos.writeTo(new FileOutputStream("byte.txt"));//写入文件

    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值