码迷,mamicode.com
首页 > 编程语言 > 详细

Java基础知识IO流(其他类)

时间:2016-05-06 16:04:35      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:

IO包中的其他类

  • 打印流 PrintWriter与PrintStream
  • 序列流 SequenceInputStream
  • 切割文件
  • 操作对象 ObjectInputStream与ObjectOutputStream
  • 管道流 PipedInputStream和PipedOutputStream
  • RandomAccessFile类 (随机访问文件)
  • 操作基本数据类型 DataInputStream和DataOutputStream类
  • 操作数组的流
    ByteArrayInputStream/ByteArrayOutputStream/CharArrayReader/CharArrayWriter/StringReader/StringWriter

打印流

该流提供了打印方法,可以将各种数据类型的数据原样打印。
PrintStream字节打印流
构造时可以直接操作文件file,能够直接操作file的类都很重要。
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
构造方法摘要
PrintStream(File file)
创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(File file, String csn)
创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
PrintStream(OutputStream out)
创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush)
创建新的打印流。
autoFlush - boolean 变量;如果为 true,则每当写入 byte 数组、调用其中一个 println 方法或写入换行符或字节 (‘\n’) 时都会刷新输出缓冲区

PrintStream(OutputStream out, boolean autoFlush, String encoding)
创建新的打印流。
PrintStream(String fileName)
创建具有指定文件名称且不带自动行刷新的新打印流。
PrintStream(String fileName, String csn)
创建具有指定文件名称和字符集且不带自动行刷新的新打印流。

PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。
构造方法摘要
PrintWriter(File file)
使用指定文件创建不具有自动行刷新的新 PrintWriter。
PrintWriter(File file, String csn)
创建具有指定文件和字符集且不带自动刷行新的新 PrintWriter。
PrintWriter(OutputStream out)
根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。
PrintWriter(OutputStream out, boolean autoFlush)
通过现有的 OutputStream 创建新的 PrintWriter。
autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区
PrintWriter(String fileName)
创建具有指定文件名称且不带自动行刷新的新 PrintWriter。
PrintWriter(String fileName, String csn)
创建具有指定文件名称和字符集且不带自动行刷新的新 PrintWriter。
PrintWriter(Writer out)
创建不带自动行刷新的新 PrintWriter。
PrintWriter(Writer out, boolean autoFlush)
创建新 PrintWriter。

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

        String line = null;

        while((line=bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;
            //直接换行且刷新缓存区
            out.println(line.toUpperCase());
            //out.flush();
        }

        out.close();
        bufr.close();

    }   
}

SequenceInputStream类

SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

构造方法摘要
SequenceInputStream(Enumeration

import java.io.*;
import java.util.*;

class  PrintStreamDemo
{
    public static void main(String[] args) throws IOException
    {
        Vector<FileInputStream> fiss=new Vector<FileInputStream>();
        fiss.add(new FileInputStream("1.txt"));
        fiss.add(new FileInputStream("2.txt"));
        fiss.add(new FileInputStream("3.txt"));

        Enumeration<FileInputStream> elements=fiss.elements();
        SequenceInputStream sis=new SequenceInputStream(elements);

        FileOutputStream fos=new FileOutputStream("4.txt");
        byte[] arr=new byte[1024];
        int length=0;
        while((length=sis.read(arr))!=-1)
        {
            fos.write(arr);
        }

        sis.close();
        fos.close();
    }   
}

切割文件

将一个文件按照一定大小切割成几个文件。也就是一个InputStream对应多个OutputStream。

import java.io.*;

class SplitDemo 
{
    public static void main(String[] args) throws IOException
    {
        FileInputStream fis=new FileInputStream("4.txt");
        byte[] arr=new byte[1024];
        int len=0;
        int count=1;
        while((len=fis.read(arr))!=-1)
        {

            FileOutputStream fos=new FileOutputStream((count++)+".txt");
            fos.write(arr,0,len);
            fos.close();

        }

         fis.close();

    }
}

操作对象

ObjectInputStream和ObjectOutputStream是可以直接操作对象的流。
意义:将堆内存的对象存储到硬盘上,对象封装的数据也随之存储到硬盘上,方便程序运行完之后再次得知对象的数据。将对象存放在硬盘上是对象的持久化存储。

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。
构造方法:
ObjectOutputStream(OutputStream out)
创建写入指定 OutputStream 的 ObjectOutputStream。
关键方法:
void writeObject(Object obj)
将指定的对象写入 ObjectOutputStream。
序列化是什么意思?
一个类想要序列化,需要实现Serializable接口。Serializable接口没有方法,没有方法的接口属于标记接口,实现该接口的类表示具备被序列化的资格。相当于猪肉只有盖了合格戳才能具备在市场上卖的资格。
序列化的原理是什么?
实际上,Serializable接口给实现它的类加了一个serialVersionUID,类在被序列化时希望有个Id标识,给编译器使用。假如一个序列化的类创建了一个对象,该对象被持久化保存带硬盘上了,然后这个类进行了修改,重新编译之后序列号发生变化,此时编译器取回硬盘上的对象时,由于序列号不同,断定为不同的类的对象。
UID实际上根据类中的成员变量算出来的,如果多次修改之后,成员变量不变,那么序列号不变。
UID可以自定义,不让java自动生成。
只能将堆内的对象序列化,不能将静态变量序列化。如果对非静态的成员也不想序列化的话,可以在变量前加上关键字 transient

import java.io.*;
class Person implements Serializable
{
    //自己确定类的UID
    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();
    }
}

管道流

通常输入流和输出流之间没有直接的关系,若想有关系需要一个数组作为一个中转站。而管道流可以将输入流和输出流对接到一起。问题是,输入流和输出流哪个先执行呢?

PipedInputStream
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。(一个线程的话,假如没有数据时,PipedInputStream就开始读数据,那么进入等待,造成堵塞)
集合中涉及到IO流的是Properties,在IO流中涉及到多线程的是管道流

管道输入流和管道输出流如何连接到一起呢? 构造方法!或connect()方法。
PipedInputStream(PipedOutputStream src)
创建 PipedInputStream,使其连接到管道输出流 src。

示例:

import java.io.*;

class PipedStreamDemo 
{
    public static void main(String[] args) throws IOException
    {
        PipedInputStream in=new PipedInputStream();
        PipedOutputStream out=new PipedOutputStream();
        in.connect(out);

        new Thread(new Read(in)).start();
        new Thread(new Write(out)).start();
    }
}

class Read implements Runnable
{
    private PipedInputStream in;
    Read(PipedInputStream in)
    {
        this.in=in;
    }
    public void run()
    {
        try
        {

            byte[] arr=new byte[1024];
            System.out.println("读之前");
            int len=in.read(arr);
            System.out.println("读之后");
            System.out.println( new String(arr,0,len));
        }
        catch (IOException e)
        {
            throw new RuntimeException("读失败");
        }
        finally
        {
            try
            {
                if(in!=null)
                    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("写之前");
            out.write("hahaha".getBytes());
            System.out.println("写之后");


        }
        catch (IOException e)
        {
            throw new RuntimeException("写失败");
        }
        finally
        {
            try
            {
                if(out!=null)
                    out.close();
            }
            catch (IOException e)
            {
               throw new RuntimeException("写失败");
            }
        }


    }

}

技术分享

RandomAccessFile类

此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

构造方法摘要
RandomAccessFile(File file, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
RandomAccessFile(String name, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。

该类不是算是IO体系中子类。
而是直接继承自Object。

但是它是IO包中成员。因为它具备读和写功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。

其实完成读写的原理就是内部封装了字节输入流和输出流。

通过构造函数可以看出,该类只能操作文件
而且操作文件还有模式:只读r,,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

特点:
1.通过seek(int n )方法改变指针的位置。读写指定位置。
2.skipBytes(int n)跳过n个字节,只能往前跳,不能往回跳。
3.可以直接读取和写入基本数据类型。如writeInt(int v),readInt()等。
4. 不用按顺序读写,可以在任意位置进行读写和修改,可以存在空格。这样有什么好处呢? 可以将文件的内容分段,用多个线程分别负责每个段的操作,这就是下载软件的原理,这样会提高效率。
示例:

import java.io.*;
class RandomAccessFileDemo 
{
    public static void main(String[] args) throws IOException
    {
        write();
        read();
    }
    public static void write()throws IOException
    {
        RandomAccessFile raf=new RandomAccessFile("rafDemo.txt","rw");
        raf.write("马闪闪".getBytes());
        raf.writeInt(25);

        raf.seek(11);
        raf.write("赵根源".getBytes());
        raf.writeInt(24);

        raf.close();
    }
    public static void read() throws IOException
    {
        RandomAccessFile raf=new RandomAccessFile("rafDemo.txt","rw");
        byte[] buf=new byte[6];
        int len=raf.read(buf);
        System.out.println(new String(buf,0,len));
        System.out.println(raf.readInt());

        raf.skipBytes(1);
        byte[] buf2=new byte[6];
        int len2=raf.read(buf2);
        System.out.println(new String(buf2,0,len2));
        System.out.println(raf.readInt());

        raf.seek(0);
        byte[] buf3=new byte[6];
        int len3=raf.read(buf3);
        System.out.println(new String(buf3,0,len3));
        System.out.println(raf.readInt());
        raf.close();
    }
}

技术分享

操作基本数据类型 DataInputStream和DataOutputStream类

DataOutputStream
数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。
writeUTF(String str): 以与机器无关方式使用 UTF-8 修改版编码将一个字符串写入基础输出流。
DataInputStream
数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。

import java.io.*;

class DataStreamDemo
{
    public static void main(String[] args)  throws IOException
    {
        write();
        read();
    }

    public static void write() throws IOException
    {
        DataOutputStream dos=new DataOutputStream(new FileOutputStream("dosDemo.txt") );
        dos.writeInt(255);
        dos.writeBoolean(true);
        dos.writeDouble(8998.655);
        dos.close();
    }
    public static void read() throws IOException
    {
        DataInputStream dis=new DataInputStream(new FileInputStream("dosDemo.txt") );
        int a=dis.readInt();
        boolean b=dis.readBoolean();
        double c=dis.readDouble();
        System.out.println(String.valueOf(a)+String.valueOf(b)+String.valueOf(c));
        dis.close();
    }

}

操作数组的流

ByteArrayInputStream和ByteArrayOutoutStream
用于操作字节数组的流对象。我们知道InputStream和OutputStream都可以对字节数组进行操作,这二者有什么区别呢?
ByteArrayInputStream :在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭,也不会产生IOException异常。
只有一个方法会有IOException,那就是writeTo(OutputStream out)方法。

在流操作规律讲解时:
源设备有,
键盘 System.in,硬盘 FileStream,内存 ArrayStream
目的设备有:
控制台 System.out,硬盘FileStream,内存 ArrayStream。
操作数组的流就是用流的读写思想来操作数据。
CharArrayReader和CharArrayWriter以及StringReader和StringWriter都是同样的道理。

示例:

import java.io.*;

class ArrayStreamDemo 
{
    public static void main(String[] args) throws IOException
    {
        byteArrayStreamTest();
        CharArrayTest();
        StringTest();
    }

    public static void byteArrayStreamTest()
    {
        ByteArrayInputStream bis=new ByteArrayInputStream("abcdefghijklmnopqrstuvwxyz".getBytes());
        ByteArrayOutputStream bos=new ByteArrayOutputStream();

        int b=0;
        while((b=bis.read())!=-1)
        {
            bos.write(b);
        }

        System.out.println(bos.toString());
    }

    public static void CharArrayTest() throws IOException
    {
        CharArrayReader car=new CharArrayReader("wo shi yi ge da huai dan".toCharArray());
        CharArrayWriter caw=new CharArrayWriter();

        int b=0;
        while((b=car.read())!=-1)
        {
            caw.write(b);
        }

        System.out.println(caw.toString());
    }

    public static void StringTest() throws IOException
    {
        StringReader sr=new StringReader("ha ha ha ha ha");
        StringWriter sw=new StringWriter();

        int b=0;
        while((b=sr.read())!=-1)
        {
            sw.write(b);
        }

        System.out.println(sw);
    }
}

技术分享

Java基础知识IO流(其他类)

标签:

原文地址:http://blog.csdn.net/u013951760/article/details/51315605

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!