java基础知识-IO流-字节流

耐得住寂寞,才能守得住繁华

1、在java中,所有的数据都是使用流读写的,流就像水流一样,将数据从一个地方带到另一个地方。
2、流是程序中的数据所经历的的路径,输入流将数据从数据源传递给程序,而输出流将数据发送到某个目的地。

流的分类

  1. 字节流
    字节流传送0-255的整数。很多类型的数据都可以表示为字节格式,包括数字数据,可执行程序,Internet通信和字节码(java虚拟机运行的类文件)。
    实际上,每种数据都可以表示为单个字节或一系列的字节。

  2. 字符流
    字符流是一种特殊的字符流,只能处理文本数据。它不同于字节流,因为java支持Unicode–该标准包含很多无法用字节表示的字符。
    对于任何涉及文本的数据,都应使用字符流,这包括文本文件,Web页,以及其他常见的数据类型。

在字节流中输出数据主要使用OutputStream类完成,输入则是InputStream类。
在字符流中输出数据主要使用Writer类完成,输入则是Reader类。
下面是他们的层次关系
IO流的继承关系
还可以分类为节点流和过滤流

  • 节点流:从特定地方读写的流类,例如:磁盘或一块内存区域。常用的节点流包括
    (1)文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件进行处理的节点流。
    (2)字符串 StringReader StringWriter 对字符串进行处理的节点流。
    (3)数 组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
    (4)管 道 PipedInputStream PipedOutputStream PipedReaderPipedWriter对管道进行处理的节点流。
  • 过滤流(包装流):对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。包装流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
    常用的包装流有
    (1)缓冲流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter—增加缓冲功能,避免频繁读写硬盘。
    (2)转换流:InputStreamReader OutputStreamReader实现字节流和字符流之间的转换。
    (3)数据流 DataInputStream DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来.

字节流

InputStream

  1. InputStream 是一个抽象类,不能直接通过创建这些类的对象来创建字节流,必须通过它的子类来创建。
  2. InputStream是所有输入流的超类。

文件输入流

文件流是最经常使用的字节流,继承了InputStream。它用于同磁盘或其他设备中的文件交换数据,这些文件可以使用文件夹路径和文件名来引用。

构造方法摘要

 public FileInputStream (File file)   throws FileNotFoundException
 public FileInputStream (String name)  throws FileNotFoundException
  1. 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 或者是系统中的路径名指定。
  2. 如果指定文件不存在,或者它是一个目录,而不是一个常规文件,抑或因为其他某些原因而无法打开进行读取,则抛出 FileNotFoundException。
public  static String filePath = "C:/Users/asus-pc/Desktop/javaProject/src/test";
	//路径名中是左划线,或者两个右划线
	public static void main(String[] args) throws FileNotFoundException {
          File file = new File(filePath);
          InputStream  testInput = new FileInputStream(file);
          InputStream testInput2 = new FileInputStream(filePath);
          //InputStream 是抽象类,要用它的子类进行实例化。
		
	}

方法摘要

public int read(byte[] b) throws IOException
   // 返回读入缓冲区的字节总数如果因为已经到达文件末尾而没有更多的数据,则返回 -1。 
public int read() throws IOException
  //该方法返回流中的下一个字节(整数类型)。如果返回-1(这不是字节值),则表明已经达到了文件流的末尾。
public int read(byte[] b, int off, int len)  throws IOException
  //	off - 目标数组 b 中的起始偏移量,len - 读取的最大字节数。
  // 读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。  
public void close()  throws IOException
  //关闭此文件输入流并释放与此流有关的所有系统资源。

示例

package test;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class testStream {
	public  static String filePath = "C:/Users/asus-pc/Desktop/javaProject/src/test/testStream.java";
	 //路径名中是左划线,或者两个右划线
	static InputStream  testInput = null;
	 static InputStream testInput2 =null;
	public static void main(String[] args) throws IOException {
          File file = new File(filePath);
           testInput = new FileInputStream(file);
           testInput2 = new FileInputStream(filePath);
          //InputStream 是抽象类,要用它的子类进行实例化。
          
          //第一种read方法
		byte bytes[] = new byte[(int) file.length()];
		//file.length()是为了获取文件的大小
		int firstSize =0;
		firstSize = testInput.read(bytes);
		System.out.println("使用第一种方法读出来的数据字节数为"+firstSize+"\n"+new String(bytes));
		  testInput.close();
		  
		//第二种读方法
         int value = -1;
         int secondSize = 0;
         System.out.println("使用第二种读法");
         while((value=testInput2.read())!=-1){
        	 secondSize++;
        	   System.out.print((char)(value));
        	   //读到的数据为 int型的,当返回值为-1时,已到达文件末尾
         }
         System.out.println("通过第二种方法总共读取了"+secondSize+"字节");
         testInput2.close();
         
         //第三种读方法
         testInput = new FileInputStream(file);//重新打开流
         int thirdSize = 0;
         thirdSize = testInput.read(bytes, 0, (int)(file.length()));
        System.out.println("使用第三种读法读取的数据字节数为"+thirdSize+"\n"+new String(bytes));
       testInput.close();   
	}

}

文件输出流

构造方法

public FileOutputStream(File file) throws FileNotFoundException
public FileOutputStream(File file, boolean append) throws FileNotFoundException
public FileOutputStream(String name) throws FileNotFoundException
public FileOutputStream(String name,boolean append)throws FileNotFoundException

1、创建一个向具有指定 name 的文件或指定 File 对象表示的文件中写入数据的输出文件流。
2、当只有一个参数时,为重新写入,当有两个参数时,如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。

扫描二维码关注公众号,回复: 4314778 查看本文章
  testOutput = new FileOutputStream("C:/Users/asuspc/Desktop/javaProject/src/test/testStream2.java");
  testOutput2 = new FileOutputStream(filePath,true);
  //可以以文件路径以及File 对象来创建FileOutputStream,第二个参数为true的表示为追加

方法概述

public void write(int b) throws IOException
//一个字节一个字节的写
public void write(byte[] b) throws IOException
//将整个b数组写进去
public void write(byte[] b,int off, int len) throws IOException
//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
//在写的时候,如果该文件不存在,则会尝试创建该文件
        //第一种写方法
        String firWrite = "first write";
        bytes=firWrite.getBytes();
        for(int i=0;i<bytes.length;i++)
        	 testOutput.write(bytes[i]);
        
        //第二种方法
        String secWrite = "second write";
       bytes=secWrite .getBytes();
        testOutput2.write(bytes);
     
        //第三种写方法
        String thiWrite = "third write";
       bytes=thiWrite .getBytes();
        testOutput2.write(bytes,0,bytes.length); 

ByteArrayInputStream,ByteArrayOutputStream

  • 文件流是从磁盘进行读写,而ByteArrayInputStream,ByteArrayOutputStream是从一块内存区域进行读写操作的
  • ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。
  • ByteArrayOutputStream类实现了一个输出流,其中的数据被写入一个 byte 数组(缓冲区)。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
  • 当缓冲区大小不够时,ByteArrayOutputStream是自动增长缓冲区的大小。
  • 利用ByteArrayInputStream和ByteArrayOutputStream可以实现将对象等其他类型与字节数组相互转换。

对象转换成数组(对象必须可以串行化)

public byte[] objectToBytes(Object obj){
		  byte bytes[] =null;
		   ByteArrayOutputStream bArrayOutputStream =new ByteArrayOutputStream();
		   try {
			ObjectOutputStream objectOutputStream =new 		 
			ObjectOutputStream(bArrayOutputStream);
		   objectOutputStream.writeObject(obj);
		   bytes =bArrayOutputStream.toByteArray();		   
		   } catch (IOException e) {
			e.printStackTrace();
		}
		   return bytes;
	}

字节数组转换成对象

public Object bytesToObject(byte bytes[]){
		  ByteArrayInputStream bArrayInputStream =new ByteArrayInputStream(bytes);
	      Object obj =null;
		  try {
			  ObjectInputStream objectInputStream =new ObjectInputStream(bArrayInputStream);
	          obj =objectInputStream.readObject();
		  } catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;  
	}

过滤流

  • 过滤流对通过现有流传递的信息进行修改。它是使用FilterInputStream或FilterOutStream的子类来创建,而这两个类也继承自InputStream,OutputStream。
  • 过滤流对基本的输入输出流进行包装,从而在输入输出数据的同时能对所传输的数据做指定类型或格式的转换,即可实现对二进制字节数据的理解和编码转换。
  • 例如: 缓冲输出流BufferedOuputStream类提供和FileOutputStream同样的写操作方法,但所有输出全部先写入缓冲区中。当写满缓冲区或者关闭输出流时,它再一次性输出到节点流,或者用flush()方法主动将缓冲区输出到流。
  • 数据输入流DataInputStream中定义了多个针对不同类型数据的读法,如readByte()、readBoolean()、readShort()、 readChar()、readInt()、readLong()、readFloat()、readDouble()、readLine()等。数据输出流DataOutputStrean也有类似的方法。但我们用该流包装节点流时,我们可以对基本数据类型进行操作。
  • 转换流(InputStreamReader,OutputStreamWriter)能实现字节流和字符流的转换。

缓冲流

  1. 缓冲流使用未被处理过的数据来填充缓冲区,程序需要数据时,将首先从缓冲区中查找,如果没有找到,再到流源中查找。
  2. 缓冲字节流是使用BufferInputStream和BufferOutputStream类表示的。
缓冲流常用方法

构造方法概述

public BufferedInputStream(InputStream in)
    //为指定的InputStream对象创建一个缓冲输入流。
    //参数:   in - 底层输入流。
    //默认大小为 8192字节
public BufferedInputStream (InputStream in,int size)
//为指定的InputStream对象创建一个缓冲区大小为size的缓冲输入流。
BufferedInputStream  bufTest = new BufferedInputStream (testInput );

为testInput 创建缓冲输入流

方法概述

public int read() throws IOException
public int read(byte[] b, int off, int len) throws IOException

和FileInputStream的用法一致

数据流

要处理未被表示为字节或字符的数据,可以使用数据输入流和数据输出流。这些流对字节流进行过滤,以便能够直接读写如下基本数据类型:boolean,byte,double,float,int,long和short

数据流常用方法

构造方法概述

public DataInputStream(InputStream in)

使用指定的底层 InputStream 创建一个 DataInputStream。

方法概述
可用于数据输入与数据输出的读写方法如下
readBoolean() , writeBoolean(boolean)
readByte() , writeByte(integer);
readDouble() , writeDouble(double)
readFloat() , writeFloat(float)
readInt() , writeInt(int)
readLong() , writeLong(long)
readShort() , writeShort(int)

下个博客在总结字符流。

猜你喜欢

转载自blog.csdn.net/kuangpeng1956/article/details/83472887