`
coach
  • 浏览: 386763 次
  • 性别: 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  
最后一段分析写的精彩。

相关推荐

    java超详细思维导图XMIND格式

    通过这个思维导图,学习者可以按照自己的进度和兴趣逐个攻克Java的各个知识点,从基础到高级,从理论到实践,逐步建立完整的知识体系。对于初学者,它能帮助快速入门;对于有经验的开发者,它能作为一个很好的复习和...

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

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

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

    ### C语言:彻底理解指针 #### 一、引言 在C语言中,指针是一种非常重要的数据类型,它能够存储内存地址,是进行高效内存管理的关键工具。本文将从多个角度深入探讨指针的概念及其应用,帮助读者建立起对指针的...

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

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

    java编程案例--10道精选的JAVA小题

    Java编程是一种广泛使用的...通过这10道精选的JAVA小题,我们可以逐一攻克Java编程的基石,加深对语言特性的理解,并逐步提高编程能力。实践中遇到的问题和解决方案将成为宝贵的经验,为日后的项目开发打下坚实基础。

    21讲吃透实时流计算2022年

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

    JAVA开发经理_java个人简历模板.doc

    JAVA 开发经理个人简历模板 根据提供的简历模板,我们可以总结出以下知识点: Java EE 和 Java ME * Java EE(Enterprise Edition):用于开发大型企业级应用程序,涉及技术包括 SSH(Spring + Struts + ...

    java程序设计实用教程(第3版)习题解答

    通过《Java程序设计实用教程(第3版)》的习题解答,你可以逐一攻克这些知识点,加深对Java的理解,提升编程实战能力。在实践中,你可以使用IDE如MyEclipse来导入并运行这些习题,这样不仅能够检验答案的正确性,还能...

    JAVA200道经典例题

    6. **输入/输出流**:JAVA的IO流系统支持文件读写、网络通信等,包括FileInputStream、FileOutputStream、BufferedReader、PrintWriter等类的使用。 7. **多线程**:JAVA提供了Thread类和Runnable接口实现多线程,...

    攻克Data动态获取网页评论,保存数据库

    【攻克Data动态获取网页评论,保存数据库】是一个关于利用特定工具——攻克Data,来抓取网页上的评论数据并存储到数据库的过程。这个过程涉及到网络爬虫技术、JSON解析以及数据库管理等多个IT领域的知识点。 1. **...

    java concurrent source code

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

    java员工转正述职报告.pdf

    - 工作表现:详细描述在试用期间完成的工作任务、项目,包括解决过的问题、技术难点的攻克以及个人贡献。 - 学习成长:在试用期间所学到的新知识、技术、工具,以及如何快速融入团队和公司文化。 - 问题与挑战:在...

    上机题java篇(全).rar!!!!

    Java编程语言是面向对象的、跨平台的编程语言,由Sun Microsystems(现为Oracle Corporation的一部分)于1995年...建议按照题目分类,逐个攻克,同时结合教材和在线资源深入学习,以达到全面提高Java编程技能的目标。

    攻克java大数类

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

    毕向东_Java基础视频源代码

    【毕向东_Java基础视频源代码】是一套由著名IT教育机构黑马程序员的资深讲师毕...每个day的文件夹代表一个阶段的学习重点,学生可以通过逐个攻克这些挑战,逐步构建自己的Java知识体系,从而成为一名熟练的Java开发者。

    大学生攻克Linux系统教程

    【大学生攻克Linux系统教程】 本教程专为对Linux操作系统感兴趣的初学者设计,旨在提供一个从零开始学习Linux的全面指南。教程内容涵盖了Linux系统的安装、基本操作、文本编辑器VI的使用、调试工具GDB的基础知识,...

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

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

    JAVA 炸弹人(2)

    这款游戏共有三关,每关都有不同的挑战等待玩家去攻克,增加了游戏的可玩性和挑战性。 在JAVA语言中,开发游戏通常涉及到以下几个关键知识点: 1. **图形用户界面(GUI)**:JAVA中的`javax.swing`和`java.awt`库...

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

    总的来说,这个“大学生攻克Linux系统教程”涵盖了从基本的命令操作到高级的系统管理和Java开发实践。通过学习,你不仅能够熟练掌握Linux系统,还能为未来在IT行业的深入发展打下坚实的基础。无论是个人兴趣还是职业...

Global site tag (gtag.js) - Google Analytics