`
coach
  • 浏览: 382911 次
  • 性别: Icon_minigender_2
  • 来自: 印度
社区版块
存档分类
最新评论

彻底攻克java流

阅读更多
类图1:


IO分两种流

字节流 InputStream OutputStream

字符流 Reader  Writer

他们都是抽象类

具体实现
字节流 FileInputStream  FileOutputStream
字符流 FileReader    FileWriter


字节流转换成字符流可以用 InputSteamReader  OutputStreamWriter

转换成BufferdReader  BufferedWriter 他们具有缓冲区

例如:读取文件 从字节流输入到字符流输入
定义一个字节流:
FileInputStream fileInputStream = new FileInputStream("d:/text.txt");  // 定义一个指向D:/TEXT.TXT 的字节流

InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
//字节流转换成InputStreamReader

BufferedReader bufferedReader = new BufferedReader(inputSteamReader);
//InputStreamReader 转换成带缓存的bufferedReader


可以把读出来的内容赋值给字符
String ss = new String();
String s;
while((s = bufferedReader.readLine())!=null){
	ss += s;
}

例如:写入文件  从字节流输出到字符流输出
FileOutputStream fileOutputStream = new FileOutputStream("d:/text.txt"); //定义一个指向D:/TEXT.TXT文件 

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);

BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);

bufferedWriter.write(s);

bufferedWriter.close();
outputStreamWriter.close();
fileOutputStream.close();














上面这个图向我们传达了这个信息:链接流链接流对象接收一个原始流对象或者另外一个链接流对象作为流源;另一方面他们对流源的内部工作方法做了相应的改变,这种改变是装饰模式所要达到的目的。比如:

  BufferedInputStream“装饰”了InputStream的内部工作方式,使得流的读入操作使用了缓冲机制。在使用了缓冲机制后,不会对每一次的流读入操作都产生一个物理的读盘动作,从而提高了程序的效率,在汲及到物理流的读入时,都应当使用这个装饰流类。

  LineNumberInputStream和PushbackInputStream也同样“装饰”了InputStream的内部工作方式,前者使得程序能够按照行号读入数据;后者能够使程序读入的过程中,退后一个字符。

  DataInputStream子类读入各种不同的原始数据类型以及String类型的数据,这一点可以从它提供的各种read方法看出来,如:readByte(),readInt(),readFloat()等。

使用基本原则:

  • 根接口是InputStream/OutputStream
  • 充当数据源的IO类有FileInputStream/FileOutputStream,ByteArrayInputStream  / ByteArrayOutputStream  等,
  • 充当装饰功能的IO类有BufferedInputStream  /   BufferedOutputStream,DataInputStream   /   DataOutputStream等,
  • 它们都是继承装饰接口FilterInputStream/FilterOutputStream。
  • 使用IO时,首先创建一个数据源IO,然后根据需要的功能创建装饰类IO,其构造函数的参数为已创建的数据源IO
常用类举例说明:
FileInputStream和FileOutputStream
    简单略

ObjectOutputStream和ObjectInputStream
    这个流的作用是,直接将一个对象转换为字节流,对象必须implements Serializable
package demo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ObjectStreamTest
{
    public static void main(String[] args)
    {
        T t = new T();
        t.k = 15;

        try
        {
            FileOutputStream fos = new FileOutputStream("d:/333.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(t);

            fos.close();
            oos.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        try
        {
            FileInputStream fis = new FileInputStream("d:/333.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);

            T t2 = (T) ois.readObject();

            System.out.println(t2.i);
            System.out.println(t2.k);
            System.out.println(t2.s);
            System.out.println(t2.j);
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }

}

@SuppressWarnings("all")
class T implements Serializable
{
    int i = 20;
    short j = 10;
    String s = "hello";
    int k = 100;
}


DataInputStream和DataOutputStream
    这个是数据流.给我们直接处理基本数据类型的接口,举个最基本的例子,如果我们要将一个float类型的数据写入文件,我们需要先转换成String类型,然后转换成字节数组,这样才能存入..现在我们可以直接用DataInputStream和DataOutputStream来解决这个问题
package demo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class DataStreamTest
{
    public static void main(String[] args)
    {
        //ByteArrayOutputStream可以临时缓存一个对象的字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos);

        try
        {
            dos.writeChar('d');
            dos.writeInt(10);
            dos.writeShort(50);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());//ByteArrayOutputStream的用法
        DataInputStream dis = new DataInputStream(bais);

        try
        {
            System.out.println(dis.available());
            System.out.println(dis.readChar());
            System.out.println(dis.readInt());
            System.out.println(dis.readShort());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        try
        {
            dos.close();
            dis.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}


BufferedInputStream和BufferedOutputStream
    BufferedInputStream当使用read()方法时,实际上是先读取buf中的数据,而不是直接对数据来源作读取。当buf中的数据不足时,BufferedInputStream才会再实现给定的InputStream对象的read()方法,从指定的装置中提取数据。
    BufferedOutputStream当使用write()方法写入数据时实际上会先将数据写到buf中,当buf已满时才会实现给定的OutputStream对象的write()方法,将buf数据写到目的地,而不是每次都对目的地作写入的动作

package demo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedStreamDemo
{
    public static final void copy(File srcFile, File distFile) throws IOException
    {
        FileInputStream fin = null;
        BufferedInputStream bis = null;
        FileOutputStream fout = null;
        BufferedOutputStream bos = null;

        try
        {
            if (distFile.exists())
            {
                distFile.delete();
            }

            byte[] data = new byte[1024];

            fin = new FileInputStream(srcFile);
            bis = new BufferedInputStream(fin);
            fout = new FileOutputStream(distFile);
            bos = new BufferedOutputStream(fout);

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

            // 将缓冲区中的数据全部写出
            bos.flush();
        }
        finally
        {
            try
            {
                if (bos != null)
                {
                    bos.close();
                }
            }
            catch (IOException e)
            {
            }
            try
            {
                if (bis != null)
                {
                    bis.close();
                }
            }
            catch (IOException e)
            {
            }
            try
            {
                if (fin != null)
                {
                    fin.close();
                }
            }
            catch (IOException e)
            {
            }
            try
            {
                if (fout != null)
                {
                    fout.close();
                }
            }
            catch (IOException e)
            {
            }
        }
    }
    
    public static void main(String[] args)
    {
        try
        {
            BufferedStreamDemo.copy(new File("c:\\test1.abs"), new File("c:\\test2.abs"));
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}


InputStreamReader和OutputStreamWriter:字符流和字节流之间的转换
    Reader 输入流对应于不同的数据源:
    FileReader 用于从文件输入;
    CharArrayReader 用于从程序中的字符数组输入;
    StringReader 用于从程序中的字符串输入;

   InputStreamReader从一个数据源读取字节,并自动将其转换成Unicode字符
    OutputStreamWriter将字符的Unicode编码写到字节输出流

package demo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class InputStreamReaderTest
{

    public static void main(String[] args)
    {
        try
        {
            FileInputStream fis = new FileInputStream("d:/222.txt");
            InputStreamReader isr = new InputStreamReader(fis);
            BufferedReader br = new BufferedReader(isr);// 这里又用BufferedReader封装起来,其实就是为了可以使用它的ReadLine方法

            FileOutputStream fos = new FileOutputStream("d:/555.txt");
            OutputStreamWriter osw = new OutputStreamWriter(fos);
            BufferedWriter bw = new BufferedWriter(osw);// 这里同样的用BufferedWriter封装起来,就是为了可以使用它的writer(String )方法..可以看API,其他的都只能write Int类型的数据或者byte类型的

            String s2 = null;

            while ((s2 = br.readLine()) != null)
            {
                bw.write(s2);
                bw.newLine();
            }

            bw.close();
            br.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}


疑问:
1、ByteArrayOutputStream和BufferedOutputStream区别
    本来这2个没法比较的,非得比较可以为:
(1)、构造方法不一样;
(2)、byte[]转换为InputStream流:InputStream sbs = new ByteArrayInputStream(byte[] buf);
(3)、InputStream转换为byte[]数组
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100]; //buff用于存放循环读取的临时数据
int rc = 0;
while ((rc = inStream.read(buff, 0, 100)) > 0) {
	swapStream.write(buff, 0, rc);
}
byte[] in_b = swapStream.toByteArray(); //in_b为转换之后的结果


2、ArrayList一个基础问题,关于 transient

ArrayList 里面定义:
    private transient Object[] elementData;  
    这里是ArrayList.elementData定义的地方,而elementData是用来存储实际内容的数组, 而transient字是表明域不能序列化,而我在这里能打印出 a b c,这个对transient怎么理解?

package demo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class WriteObject
{
    public static void main(String[] args)
    {
        ArrayList<String> al = new java.util.ArrayList<String>();
        al.add("a");
        al.add("b");
        al.add("c");
        try
        {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(stream);
            out.writeObject(al);
            byte[] alBytes = stream.toByteArray();

            ArrayList<String> all = (ArrayList<String>) new ObjectInputStream(new ByteArrayInputStream(alBytes)).readObject();
            for (String s : all)
            {
                System.out.println(s);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


序列化有2种方式:

A、只是实现了Serializable接口。

  序列化时,调用java.io.ObjectOutputStream的defaultWriteObject方法,将对象序列化。

注意:此时transient修饰的字段,不会被序列化。

B、实现了Serializable接口,同时提供了writeObject方法。

  序列化时,会调用该类的writeObject方法。而不是java.io.ObjectOutputStream的defaultWriteObject方法。

注意:此时transient修饰的字段,是否会被序列化,取决于writeObject。


  • 大小: 265.3 KB
  • 大小: 112.8 KB
  • 大小: 93.1 KB
  • 大小: 15.1 KB
  • 大小: 47.8 KB
分享到:
评论
1 楼 cwqcwqmax9 2013-11-29  
最后一段分析写的精彩。

相关推荐

    c语言:我眼中的指针(教你彻底认识指针)

    c语言:我眼中的指针(教你彻底认识指针) 我眼中的指针 c语言:我眼中的指针(教你彻底认识指针)

    铁道部借助英特尔技术攻克多项远程管理挑战

    兰州铁路局和上海铁路局采用英特尔:registered: 主动管理技术(英特尔:registered: AMT)的电脑用于远程电脑管理,并进一步将英特尔:registered: 主动管理技术集成到了自己的电子文件交付系统(Electronic Document ...

    c++虚函数表解析(彻底攻克继承和虚函数)

    彻底搞清楚继承是个什么东西 彻底搞清楚虚函数和虚函数表是个什么东西

    21讲吃透实时流计算2022年

    │ 开篇词 攻克实时流计算难点,掌握大数据未来!.mp4 │ 01 实时流计算的通用架构.mp4 │ 08 性能调优:如何优化流计算应用?.mp4 │ 09 流数据操作:最基本的流计算功能.mp4 │ 10 时间维度聚合计算:如何在...

    think in java4源代码

    经典的think in java4,所有源码,帮你早日攻克java学习的堡垒!!!

    java多线程核心技术

    很多人学习完JavaSE/JavaEE之后想往更深入的技术进行探索,比如对大数据、分布式、高并发类的专题进行攻克时,立即遇到针对java.lang包中线程类的学习,但线程类的学习并不像JDBC一样简单,学习曲线陡峭,多弯路与...

    java concurrent source code

    很多人学习完JavaSE/JavaEE之后想往更深入的技术进行探索,比如对大数据、分布式、高并发类的专题进行攻克时,立即遇到针对java.lang包中线程类的学习,但线程类的学习并不像JDBC一样简单,学习曲线陡峭,多弯路与...

    攻克java大数类

    我不想学习了 不,我想!! 这篇博客作为我学习大数类的笔记。(我会持续更新的) BigInteger操作大整数 BigDecimal指定小数的保留位数 首先,long的范围是:-2^63 ~ 2^63-1 超过这个范围,就是用大数类,最好用...

    24学时攻克c++_笔记

    24学时攻克c++_ 笔记

    24学时攻克c++

    24学时攻克c++,这本书不错,不过只上传了23页

    零基础学Java,通俗易懂的Java入门课

    攻克面向对象、多线程等技术难点;独立用 Java 编写一款小游戏。 课程介绍:在最权威的 TIOBE 编程语言排名榜单上,Java 常年稳居第一,可以说是世界上应用最为广泛的一门语言。包括阿里巴巴、京东、去哪儿网、...

    24小时攻克c++代码

    24小时攻克c++代码

    下面是我对于JAVA学习的一些心得体会

    JAVA,作为一门流行的编程语言,拥有广泛的应用领域,从桌面应用程序到大型企业级应用,再到微服务架构,都能见到JAVA的身影。下面是我对于JAVA学习的...只要我们保持热情和耐心,就能攻克任何难关,掌握JAVA这门语言

    Java 最新面试宝典 java 面试宝典 java 最新面试宝典 Java面试Java 工程师进阶知识完全扫盲

    面试技术攻克篇 Java基础知识 Java Web 数据库原理 设计模式 数据结构与算法 海量数据处理 SSM企业级应用(Spring+SpringMVC+Mybatis) SpringBoot+SpringCloud 需要完整版Java面试宝典的朋友,只需要关注...

    Java PDF转图片 完美方案 绝对可用

    项目中遇到此需求,网上搜罗各种资料,都没有100%解决问题,要么丢字符,要么格式错乱,要么乱码,潜心攻克几天,终于找到完美方案,现分享给各位同仁; 基于apache pdfbox库实现Java PDF转图片,带源码和pom文件;...

    java重点知识详解

    学习java有段时间了,从开始的迷茫到最后的转折,经历了很多很多,但最后还是攻克了,本资料是根据自己的思想来写的,重点理解了java中难理解的一些东西,以我自己的观点来解释,相信对各位会有很大的帮助的。...

    大学生攻克Linux系统教程.rar

    大学生攻克Linux系统教程(又名天下没有难学的Linux)。一位在校大学生整理的教程,献给每一位要征服Linux的学习者-五星级的Linux教程。 本书汇集众多Linux学习者的心血与贡献,有很多作者在默默的为你呼喊,感谢...

    8天攻克8000英语词汇

    8天攻克8000词汇,word版,方便学习,背单词的好东东

    一天攻克平衡小车(含STC15及STM32)

    一天攻克平衡小车(含STC15及STM32) 一天攻克平衡小车(含STC15及STM32) 一天攻克平衡小车(含STC15及STM32) 一天攻克平衡小车(含STC15及STM32)

    大学生攻克Linux系统教程(又名天下没有难学的Linux)

    大学生攻克Linux系统教程(又名天下没有难学的Linux)

Global site tag (gtag.js) - Google Analytics