GVKun编程网logo

给定一个Java InputStream,如何确定流中的当前偏移量?(java流指定字符编码)

21

本篇文章给大家谈谈给定一个JavaInputStream,如何确定流中的当前偏移量?,以及java流指定字符编码的知识点,同时本文还将给你拓展(转)java中outputStream与inputStr

本篇文章给大家谈谈给定一个Java InputStream,如何确定流中的当前偏移量?,以及java流指定字符编码的知识点,同时本文还将给你拓展(转)java中outputStream与inputStream的相互转换、(转)java的InputStream和OutputStream的理解、013-java中的IO操作-InputStream/Reader、OutputStream/Writer、bufferedinputstream FileInputStream inputstream的比较等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

给定一个Java InputStream,如何确定流中的当前偏移量?(java流指定字符编码)

给定一个Java InputStream,如何确定流中的当前偏移量?(java流指定字符编码)

我想要类似通用,可重用的getPosition()方法,该方法将告诉我从流的起点读取的字节数。理想情况下,我希望它可以与所有InputStream一起使用,这样当我从不同的来源获得它们时,就不必包装它们中的每一个。

这样的野兽存在吗?如果不是,那么有人可以推荐现有的计数实现InputStream吗?

答案1

小编典典

看一下Commons
IO包中的CountingInputStream。它们也很好地收集了其他有用的InputStream变体。

(转)java中outputStream与inputStream的相互转换

(转)java中outputStream与inputStream的相互转换

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class ConvertUtil {
    // inputStream转outputStream
    public ByteArrayOutputStream parse(final InputStream in) throws Exception {
        final ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        int ch;
        while ((ch = in.read()) != -1) {
            swapStream.write(ch);
        }
        return swapStream;
    }

    // outputStream转inputStream
    public ByteArrayInputStream parse(final OutputStream out) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos = (ByteArrayOutputStream) out;
        final ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
        return swapStream;
    }

    // inputStream转String
    public String parse_String(final InputStream in) throws Exception {
        final ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        int ch;
        while ((ch = in.read()) != -1) {
            swapStream.write(ch);
        }
        return swapStream.toString();
    }

    // OutputStream 转String
    public String parse_String(final OutputStream out) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos = (ByteArrayOutputStream) out;
        final ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
        return swapStream.toString();
    }

    // String转inputStream
    public ByteArrayInputStream parse_inputStream(final String in) throws Exception {
        final ByteArrayInputStream input = new ByteArrayInputStream(in.getBytes());
        return input;
    }

    // String 转outputStream
    public ByteArrayOutputStream parse_outputStream(final String in) throws Exception {
        return parse(parse_inputStream(in));
    }
}

 

(转)java的InputStream和OutputStream的理解

(转)java的InputStream和OutputStream的理解

1、在java中stream代表一种数据流(源),javaio的底层数据元,---(想像成水龙头)
2、任何有能力产生数据流(源)的javaio对象就可以看作是一个InputStream对象
既然它能产生出数据,我们就可以将数据取出,java对封装的通用方法就read()方法了--(出水龙头)
3、任何有能力接收数据源(流)的javaio对象我们就可以看作是一个OutputStream对象
同样,它能接收数据,我们就可以调用它的write方法,来让它接收数据--(进水龙头了,呵呵)
4、当然,我们可以在Inputstream和OutputStream数据源的基础上,从实际需要触发,
来重新封装出不同性能机制的输入、输出流了,java.io包中提供了很丰富的输入、输出流对象,如:
基于字节流的stream:
DataOutputStream----DataInputStream:
FileOutputStream-----FileInputStream:
.............等,可以用InputStream和OutputStream从JDK文档查阅
基于字符流的stream(典型的以write和reader来标识的):
FileWriter---FileReader:
StringWriter---StringReader:
.........等,你自己可以用Writer和Reader从JDK文档里头查看说明
stream应该是水龙头里的水资源,
InputStream:是一个出水龙头(把水封装在里头)的一个实物对象,该对象的read方法呢,就想成这个
出水龙头这一机制对象的开关钮,你read或openStream(其他对象包容InputStream对象的对象方法)一下呢,就等于打开了出水龙头的按钮,水就出来了,里头封装的水是什么性质的呢,你就用相应的容器来装,如string或byte[].....
OutputStream:你就在InputStream基础上反着想就ok了 
-------------------------------------------------------------------------------------------------------------------------
OutputStream
(1)输出数据
   void write(int b)往流中写一个字节b
   void write(byte b[])往流中写一个字节数组b
   void write(byte b[],int off,int len)把字节数组b中从下标off开始,长度为len的字节写入流中
 (2)
   flush()刷空输出流,并输出所有被缓存的字节
   由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。
(3)关闭流
   close()流操作完毕后必须关闭。
------------------------------------------------------------------------------------------------------------------------
InputStream
(1)从流中读取数据
   int read() 读取一个字节,返回值为所读得字节
   int read(byte b[]) 读取多个字节,放置到字节数组b中,通常读取的字节数量为b的长度,返回值为实际独取的
 字节的数量。
   int read(byte b[] ,int off,int len)读取len个字节,放置到以下标off开始字节数组b中,返回值为实际
 读取的字节的数量。
   int available() 返回值为流中尚未读取的字节的数量。
   long skip(long n);读指针跳过n个字节不读,返回值为实际跳过的字节数量
(2)关闭流
   close() 流操作完毕后必须关闭
(3)使用输入流中的标记
   void mark(int readlimit)纪录当前指针的所在位置.readlimit表示读指针读出的readlimit个字节后 所标记的指针位置才实效。
   void reset() 把读指针重新指向用mark方法所记录的位置
   boolean markSupported() 当前的流是否支持读指针的记录功能。
-----------------------------------------------------------------------------------------------------------------------

Java IO通过Stream(流)来实现。关于流,可以理解为是一种“数据的管道”。管道中流动的东西可以是基于字节,也可以是基于字符的等。就好像管道里面可以流动水,也可以流动石油一样。

而对应于流还有一个概念:输入、输出设备。这些设备可以是磁盘文件、键盘(输入设备)、显示器(输出设备)、打印机(输出设备)、网络套接字等等。

下面,我们就来了解“流”。

Java中定义了两种类型的流:字节型,和字符型。

字节流:处理字节的输入和输出。包括读写二进制数据等方面的内容。

字符流:处理字符的输入和输出。他采用的是Unicode编码,可以实现国际化。使用字符流的另外一个好处就是:字符流比字节流更有效率。

字节流:

字节流包含两个顶层抽象类:InputStream和OutputStream。

1:字节流的两个顶层类是抽象类,分别是:InputStream和OutputStream。

2:每个抽象类都有子类来实现具体的功能,处理不同的设备的输入和输  出。

下面简单介绍字节流的几个常用子类:

字节流类功能简单介绍

DataInputStream包含了读取Java标准数据类型的输入流

DataOutputStream包含了写Java标准数据类型的输出流

ByteArrayInputStream从字节数组读取的输入流

ByteArrayOutputStream写入字节数组的输出流

FileInputStream从文件读入的输入流

FileOutputStream写入文件的输出流

PrintStream包含最常见的Print()和Println()的输出流

PushbackInputStream返回一个字节到输入流,主要用于编译器的实现

PipedInputStream输出管道

PipedOutputStream输入管道

SequenceInputStream将n个输入流联合起来,一个接一个按一定顺序读取

RandomAccessFile随机访问文件

BufferInputStream缓冲输入流

BufferOutputStream缓冲输出流

FilterInputStream实现了InputStream Interface

FilterOutputStream实现了OutputStream Interface

InputStream抽象类,描述流的输入

OutputStream抽象类,描述流的输入

抽象类InputStream和OutpurStream定义了实用的方法,其中最主要的是read()和write()。这两个方法在InputStream和OutputStream中声明为抽象方法,由子流类overwrite实现。

2:每个抽象类都有子类来实现具体的功能,处理不同的设备的输入和输  出。

下面简单介绍字节流的几个常用子类:

DataInputStream包含了读取Java标准数据类型的输入流

DataOutputStream包含了写Java标准数据类型的输出流

ByteArrayInputStream从字节数组读取的输入流

ByteArrayOutputStream写入字节数组的输出流

FileInputStream从文件读入的输入流

FileOutputStream写入文件的输出流

PrintStream包含最常见的Print()和Println()的输出流

PushbackInputStream返回一个字节到输入流,主要用于编译器的实现

PipedInputStream输出管道

PipedOutputStream输入管道

SequenceInputStream将n个输入流联合起来,一个接一个按一定顺序读取

RandomAccessFile随机访问文件

BufferInputStream缓冲输入流

BufferOutputStream缓冲输出流

FilterInputStream实现了InputStream Interface

FilterOutputStream实现了OutputStream Interface

InputStream抽象类,描述流的输入

OutputStream抽象类,描述流的输入

抽象类InputStream和OutpurStream定义了实用的方法,其中最主要的是read()和write()。这两个方法在InputStream和OutputStream中声明为抽象方法,由子流类overwrite实现。


013-java中的IO操作-InputStream/Reader、OutputStream/Writer

013-java中的IO操作-InputStream/Reader、OutputStream/Writer

一、概述

  IO流用来处理设备之间的数据传输,上传文件和下载文件,Java对数据的操作是通过流的方式,Java用于操作流的对象都在IO包中。

  流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

  注:java把所有的传统的流类型都放到在java.io包下,用于实现输入和输出功能。

1.1、IO流分类

  按照流的不同方向分为:输入流和输出流,

    凡是含有in的,都可理解为输入流,输入流即从文件读取到程序,只能从中读取数据,而不能向其写入数据,

    凡是含有out的,都可以理解为输出流,输出流即从程序输出到文件,只能向其写入数据,而不能向其读取数据。

    输入,输出都是从程序运行所在的内存的角度来划分的。

  按照实现功能不同可以分为:节点流和处理流。

    可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,称为节点流。节点流也被称为低级流。

    处理流则用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能。处理流也被称为高级流。

  按照数据类型【单位分】:字节流:InputStream(字节输入流)、OutputStream(字节输出流);字符流:Reader(字符输入流)、Writer(字符输出流);因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。

1.1.1、字节流与字符流区别

  本质区别只有一个:字节流是原生的操作,而字符流是经过处理后的操作。

  在进行网络数据传输、磁盘数据保存所保存所支持的数据类型只有:字节。

  而所有磁盘中的数据必须先读取到内存后才能进行操作,而内存中会帮助我们把字节变为字符。字符更加适合处理中文。  

  读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

  处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

  字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,

  结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。

  首先必须要明确一点,通过任何终端(网络、文件)读取或者输出的数据都一定是字节,字符是经过内存处理后的数据。

    字符输入:字节(磁盘)–> 自动转换为 –>字符(内存);

    字符输出:字符(内存)–> 自动转换为–>字节(磁盘);

  在利用字符流输出的时候,所有的内容实际上都只是输出到了缓冲区中(内存)。在使用close()方法关闭的时候会将我们缓冲区的数据进行输出,如果没有关闭,那么就将无法进行输出,此时可以利用flush()方法进行强制的输出。

  字符使用到了缓冲区,而字节流没有使用到缓冲区。

  如果处理中文使用字符流,其他的任何数据都使用字节流。

1.2、操作流程

  1、创建File类对象 ,主要是指明要操作的文件路径;
  2、根据字节流或字符流的子类实例化父类对象 ;
  3、进行数据的读取或写入操作;
  4、关闭流(close());

  注意:对于IO操作属于资源处理,所有的资源处理操作(IO操作、数据库操作、网络)最后必须要进行关闭。

1.3、流原理浅析

  java Io流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java Io流的40多个类都是从如下4个抽象类基类中派生出来的。

    InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。

    OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

  对于InputStream和Reader而言,它们把输入设备抽象成为一个”水管“,这个水管的每个“水滴”依次排列,如图15.5所示: 

  字节流和字符流的处理方式其实很相似,只是它们处理的输入/输出单位不同而已。输入流使用隐式的记录指针来表示当前正准备从哪个“水滴”开始读取,每当程序从InputStream或者Reader里面取出一个或者多个“水滴”后,记录指针自定向后移动;除此之外,InputStream和Reader里面都提供了一些方法来控制记录指针的移动。

  

  对于OutputStream和Writer而言,它们同样把输出设备抽象成一个”水管“,只是这个水管里面没有任何水滴,如图15.6所示:

  当执行输出时,程序相当于依次把“水滴”放入到输出流的水管中,输出流同样采用隐示指针来标识当前水滴即将放入的位置,每当程序向OutputStream或者Writer里面输出一个或者多个水滴后,记录指针自动向后移动。 

     

  以上显示了java Io的基本概念模型,除此之外,Java的处理流模型则体现了Java输入和输出流设计的灵活性。处理流的功能主要体现在以下两个方面。

  • 性能的提高:主要以增加缓冲的方式来提供输入和输出的效率。
  • 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入和输出大批量的内容,而不是输入/输出一个或者多个“水滴”。

  处理流可以“嫁接”在任何已存在的流的基础之上,这就允许Java应用程序采用相同的代码,透明的方式来访问不同的输入和输出设备的数据流。图15.7显示了处理流的模型。

    

1.4、java输入/输出流体系中常用的流的分类表  

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串     StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流     InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream    
抽象基类 FilterInputStream FilterOutputStream FilterReader FilterWriter
打印流   PrintStream   PrintWriter
推回输入流 PushbackInputStream   PushbackReader  
特殊流 DataInputStream DataOutputStream    

注:表中粗体字所标出的类代表节点流,必须直接与指定的物理节点关联:斜体字标出的类代表抽象基类,无法直接创建实例。

二、常用IO流基础用法

2.1、 IO体系的基类(InputStream/Reader,OutputStream/Writer)

  字节流和字符流的操作方式基本一致,只是操作的数据单元不同——字节流的操作单元是字节,字符流的操作单元是字符。

2.1.1、InputStream和Reader输入流

  是所有输入流的抽象基类,本身并不能创建实例来执行输入,但它们将成为所有输入流的模板,所以它们的方法是所有输入流都可使用的方法。

  a、在InputStream里面包含如下3个方法。

  • int read(); 从输入流中读取单个字节(相当于从图15.5所示的水管中取出一滴水),返回所读取的字节数据(字节数据可直接转换为int类型)。
  • int read(byte[] b)从输入流中最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数。
  • int read(byte[] b,int off,int len); 从输入流中最多读取len个字节的数据,并将其存储在数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数。

  b、在Reader中包含如下3个方法。

  • int read(); 从输入流中读取单个字符(相当于从图15.5所示的水管中取出一滴水),返回所读取的字符数据(字节数据可直接转换为int类型)。
  • int read(char[] b)从输入流中最多读取b.length个字符的数据,并将其存储在字节数组b中,返回实际读取的字符数。
  • int read(char[] b,int off,int len); 从输入流中最多读取len个字符的数据,并将其存储在数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字符数。

  直到read(char[] chuf)或者read(byte[] b)方法返回-1,即表明到了输入流的结束点。 

  c、InputStream和Reader提供的一些移动指针的方法:

  • void mark(int readAheadLimit); 在记录指针当前位置记录一个标记(mark)。
  • boolean markSupported(); 判断此输入流是否支持mark()操作,即是否支持记录标记。
  • void reset(); 将此流的记录指针重新定位到上一次记录标记(mark)的位置。
  • long skip(long n); 记录指针向前移动n个字节/字符。

2.1.2、OutputStream和Writer输出流

  两个流都提供了如下三个方法:

  • void write(int c); 将指定的字节/字符输出到输出流中,其中c即可以代表字节,也可以代表字符。
  • void write(byte[]/char[] buf); 将字节数组/字符数组中的数据输出到指定输出流中。
  • void write(byte[]/char[] buf, int off,int len ); 将字节数组/字符数组中从off位置开始,长度为len的字节/字符输出到输出流中。

  因为字符流直接以字符作为操作单位,所以Writer可以用字符串来代替字符数组,即以String对象作为参数。Writer里面还包含如下两个方法。

  • void write(String str); 将str字符串里包含的字符输出到指定输出流中。
  • void write (String str, int off, int len); 将str字符串里面从off位置开始,长度为len的字符输出到指定输出流中。

2.2、使用

以下包含内容:

  2.2.1、基础文件流【FileInputStream/FileReader ,FileOutputStream/FileWriter】

  2.2.2、缓冲流【BufferedInputStream/BufferedReader, BufferedOutputStream/BufferedWriter】

  2.2.3、转换流的使用(InputStreamReader/OutputStreamWriter)

  2.3.4、对象流的使用(ObjectInputStream/ObjectOutputStream)

  2.3.5、字节数组内存流【ByteArrayInputStream、ByteArrayOutputStream

  2.3.6、打印流【PrintStream、PrintWriter】

  2.3.7、随机访问流【RandomAccessFile】

  2.3.8、合并流【SequenceInputStream】  

  2.3.9、数据流【DataInputStream、DataOutputStream】

  2.3.10、管道流【PipedInputStream(字节输入流),PipedOutStream(字节输出流),PipedReader(字符输入流),PipedWriter(字符输出流)】

  2.3.11、异步流【NIO】

2.2.1、基础文件流【FileInputStream/FileReader ,FileOutputStream/FileWriter】

  参看代码:common 的 common-iostream

  注:上面程序最后使用了fis.close()来关闭该文件的输入流,与JDBC编程一样,程序里面打开的文件IO资源不属于内存的资源,垃圾回收机制无法回收该资源,所以应该显示的关闭打开的IO资源。Java 7改写了所有的IO资源类,它们都实现了AntoCloseable接口,因此都可以通过自动关闭资源的try语句来关闭这些Io流。 

  注: 使用java的io流执行输出时,不要忘记关闭输出流,关闭输出流除了可以保证流的物理资源被回收之外,可能还可以将输出流缓冲区中的数据flush到物理节点中里(因为在执行close()方法之前,自动执行输出流的flush()方法)。java很多输出流默认都提供了缓存功能,其实我们没有必要刻意去记忆哪些流有缓存功能,哪些流没有,只有正常关闭所有的输出流即可保证程序正常。

2.2.2、缓冲流【BufferedInputStream/BufferedReader, BufferedOutputStream/BufferedWriter】

  参看代码:common 的 common-iostream

  注意:当我们使用处理流套接到节点流上的使用的时候,只需要关闭最上层的处理就可以了。java会自动帮我们关闭下层的节点流。

2.2.3、转换流的使用(InputStreamReader/OutputStreamWriter)

  java使用System.in代表输入。即键盘输入,但这个标准输入流是InputStream类的实例,使用不太方便,而且键盘输入内容都是文本内容,所以可以使用InputStreamReader将其包装成BufferedReader,利用BufferedReader的readLine()方法可以一次读取一行内容

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        try {
            // 将System.in对象转化为Reader对象
            InputStreamReader reader = new InputStreamReader(System.in);
            //将普通的Reader包装成BufferedReader
            BufferedReader bufferedReader = new BufferedReader(reader);
            String buffer = null;
            while ((buffer = bufferedReader.readLine()) != null) {
                // 如果读取到的字符串为“exit”,则程序退出
                if (buffer.equals("exit")) {
                    System.exit(1);
                }
                //打印读取的内容
                System.out.print("输入内容:" + buffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }
}

  上面程序将System.in包装成BufferedReader,BufferedReader流具有缓存功能,它可以一次读取一行文本——以换行符为标志,如果它没有读到换行符,则程序堵塞。等到读到换行符为止。运行上面程序可以发现这个特征,当我们在控制台执行输入时,只有按下回车键,程序才会打印出刚刚输入的内容。

2.3.4、对象流的使用(ObjectInputStream/ObjectOutputStream)

  参看代码:common 的 common-iostream中ObjectStreamDemo

  注:ObjectInputStream(对象输入流)继承于InputStream,ObjectOutputStream(对象输出流)继承于OutputStream。

  对象流是将对象的基本数据和图形实现持久存储。ObjectOutputStream实际是在对流进行序列化操作,ObjectInputStream实际是在对流进行反序列化操作,要实现序列化,必须实现Serializable接口,否则是无法进行序列化和反序列化的,

  如果对象中的属性加了transient和static关键字的话,则该属性不会被序列化。

  常用的方法是:readObject(),从ObjectInputStream读取对象;writeObject(Object obj),将指定的对象写入ObjecctOutputStream;close(),关闭该流

2.3.5、字节数组内存流【ByteArrayInputStream、ByteArrayOutputStream

  参看代码:common 的 common-iostream   

  ByteArrayInputStream(内存输入流)继承于InputStream,ByteArrayOutputStream(内存输出流)继承于OutputStream。

  内存流是关不掉的,一般用来存放一些临时性的数据,理论值是内存大小。

2.3.6、打印流【PrintStream、PrintWriter】

  参看代码:common 的 common-iostream中PrintStreamAndWriterDemo 

2.3.7、随机访问流【RandomAccessFile】

  参看代码:common 的 common-iostream中RandomAccessFileDemo

2.3.8、合并流【SequenceInputStream】

  参看代码:common 的 common-iostream中SequenceInputStreamDemo

2.3.9、数据流【DataInputStream、DataOutputStream】

  DataOutputStream数据输出流允许应用程序将基本Java数据类型写到基础输出流中,而DataInputStream数据输入流允许应用程序以机器无关的方式从底层输入流中读取基本的Java类型.

  参看代码:common 的 common-iostream中DataStreamDemo

2.3.10、管道流【PipedInputStream(字节输入流),PipedOutStream(字节输出流),PipedReader(字符输入流),PipedWriter(字符输出流)】

  在java中,PipedOutputStreamPipedInputStream分别是管道输出流和管道输入流。

  它们的作用是让多线程可以通过管道进行线程间的通讯。在使用管道通信时,必须将PipedOutputStream和PipedInputStream配套使用。

  使用管道通信时,大致的流程是:我们在线程A中向PipedOutputStream中写入数据,这些数据会自动的发送到与PipedOutputStream对应的PipedInputStream中,进而存储在PipedInputStream的缓冲中;此时,线程B通过读取PipedInputStream中的数据。就可以实现,线程A和线程B的通信。  

  参看代码:common 的 common-iostream中pipedstream

2.3.11、异步流【NIO】

  io流大体分为BIO,AIO,NIO,常用的基本就是BIO,也就是之前文章所介绍的那些,接下来我们来大概了解一下NIO。

  传统io是靠字节或字符来传输,nio是靠块传输,也就是一个一个的buffer速度相对于较快。传统io是阻塞型io,nio是非阻塞型io。多适用于进行流畅的网络读写操作。

  参看代码:common 的 common-iostream中NIODemo

 

  

2.4、何为NIO,和传统Io有何区别

  我们使用InputStream从输入流中读取数据时,如果没有读取到有效的数据,程序将在此处阻塞该线程的执行。其实传统的输入里和输出流都是阻塞式的进行输入和输出。 不仅如此,传统的输入流、输出流都是通过字节的移动来处理的(即使我们不直接处理字节流,但底层实现还是依赖于字节处理),也就是说,面向流的输入和输出一次只能处理一个字节,因此面向流的输入和输出系统效率通常不高。 

  从JDk1.4开始,java提供了一系列改进的输入和输出处理的新功能,这些功能被统称为新IO(NIO)。新增了许多用于处理输入和输出的类,这些类都被放在java.nio包及其子包下,并且对原io的很多类都以NIO为基础进行了改写。新增了满足NIO的功能。 

  NIO采用了内存映射对象的方式来处理输入和输出,NIO将文件或者文件的一块区域映射到内存中,这样就可以像访问内存一样来访问文件了。通过这种方式来进行输入/输出比传统的输入和输出要快的多。

  JDk1.4使用NIO改写了传统Io后,传统Io的读写速度和NIO差不了太多。 

2.5、文件拷贝

  参看代码:common 的 common-iostream中CopyFileDemo

  1024字节数组复制并用了缓冲流 的方式效率最高  

2.6、小结

  • 如果是操作二进制文件那我们就使用字节流,如果操作的是文本文件那我们就使用字符流。
  • 尽可能的多使用处理流,这会使我们的代码更加灵活,复用性更好。

 

 

 

 

 

 

 

 

地方

bufferedinputstream FileInputStream inputstream的比较

bufferedinputstream FileInputStream inputstream的比较

BufferedInputStream类相比InputStream类,提高了输入效率,增加了输入缓冲区的功能

 

不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低

带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多

 

InputStream流是指将字节序列从外设或外存传递到应用程序的流
BufferedInputStream流是指读取数据时,数据首先保存进入缓冲区,其后的操作直接在缓冲区中完成。

 

继承关系是这样的:
Java.lang.Object
     Java.io.InputStrean
          Java.io.FilterInputStream
                Java.io.BufferedInputStream

 

FileInputStream是字节流,BufferedInputStream是字节缓冲流,使用BufferedInputStream读资源比FileInputStream读取资源的效率高(BufferedInputStream的read方法会读取尽可能多的字节),且FileInputStream对象的read方法会出现阻塞;

 

BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。

当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。

BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。

今天的关于给定一个Java InputStream,如何确定流中的当前偏移量?java流指定字符编码的分享已经结束,谢谢您的关注,如果想了解更多关于(转)java中outputStream与inputStream的相互转换、(转)java的InputStream和OutputStream的理解、013-java中的IO操作-InputStream/Reader、OutputStream/Writer、bufferedinputstream FileInputStream inputstream的比较的相关知识,请在本站进行查询。

本文标签: