一、字节输入流InputStream 和 字节输出流outputStream

java 后台 file 转成InputStreamResource java中fileoutputstream_输入流

ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。

ObjectInputStream 和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。意思是FileInputStream类可以通过一个String路径名创建一个对象,FileInputStream(String name)。而DataInputStream必须装饰一个类才能返回一个对象,DataInputStream(InputStream in)。

java 后台 file 转成InputStreamResource java中fileoutputstream_数据_02

ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,

ObjectOutputStream 和所有FilterOutputStream的子类都是装饰流。具体例子跟InputStream是对应的。

1、FileInputStream

FileInputStream(File

通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。

 

FileInputStream(String

通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

2、FileInputStream

FileOutputStream(File

创建文件输出流以写入由指定的 File对象表示的文件。

FileOutputStream(File

创建文件输出流以写入由指定的 File对象表示的文件。

 

FileOutputStream(String

创建文件输出流以指定的名称写入文件。

FileOutputStream(String

创建文件输出流以指定的名称写入文件。

(1)、读文件内容

public class FileInputStreamTest {
	public static void main(String[] args) throws IOException {
		FileInputStream fin = new FileInputStream("src\\IOTest\\testfile.txt");
		byte[] b=new byte[1024];
                 //一次从该输入流读取最多 b.length个字节的数据
		fin.read(b);
		fin.close();
		System.out.println(new String(b));	
	}
}

(2)、写内容进文件

public class OutputStreamTest {
	public static void main(String[] args) throws IOException {
	    FileOutputStream fos = new FileOutputStream("src\\IOTest\\write.txt");
	    String str="Hello IOStream";
	    byte[] b=str.getBytes();
	    //将 b.length个字节从指定的字节数组写入此文件输出流。 
	    fos.write(b);
	    fos.close();
	}
}

      如果文件不存在,则创建一个;如果文件存在,则覆盖其中的所有内容。

     想要在存在的文件中追加内容:FileOutputStream fos = new FileOutputStream("src\\IOTest\\write.txt",true);会把新的内容直接加在后面。

(3)复制文件内容

public class CopyFileTest {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("src\\IOTest\\testfile.txt");
		FileOutputStream fos = new FileOutputStream("src\\IOTest\\copy.txt");
		// 创建一个1M大小的缓冲区,用来存放输入流中的字节
		byte[] buff = new byte[1024 * 1024];
		// 用来保存实际读到的字节数
		int len = 0;
		while ((len = fis.read(buff)) != -1) {
			fos.write(buff, 0, len);
		}
		fis.close();
		fos.close();
	}
}

二、缓冲流-BufferedInputStream、BufferedOutputStream

1、简介:   

   BufferedInputStreamBufferedOutputStream这两个类分别是FilterInputStreamFilterOutputStream的子类,作为装饰器子类,使用它们可以防止每次读取/发送数据时进行实际的写操作,代表着使用缓冲区。

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

(2)带缓冲的流:一次可以读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!BufferedInputStreamBufferedOutputStream类就是实现了缓冲功能的输入流/输出流。使用带缓冲的输入输出流,效率更高,速度更快。

注意:BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。

2、总结:

  • BufferedInputStream 是缓冲输入流。它继承于FilterInputStream
  • BufferedInputStream 的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持mark()标记reset()重置方法
  • BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

3、看看构造方法以及常用方法:

(1)BufferedInputStream

//创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
//创建一个内部缓冲区数组并将其存储在 buf 中,该buf的大小默认为8192。
public BufferedInputStream(InputStream in);
 
//创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
//创建一个长度为 size 的内部缓冲区数组并将其存储在 buf 中。
public BufferedInputStream(InputStream in,int size);

 

       从构造方法中我们可以知道BufferedInputStream没有无参构造方法,它必须传入一个InputStream(一般是FileInputStream),来一起使用,以提高读写效率。

常用方法:

//从该输入流中读取一个字节
public int read();
 
//从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。
public int read(byte[] b,int off,int len);

(2)BufferedOutputStream

//使用默认大小、底层字节输出流构造bos。默认缓冲大小是 8192 字节( 8KB )
//创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
public BufferedOutputStream(OutputStream out);
 
//创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
public BufferedOutputStream(OutputStream out,int size);

常用方法:

//向输出流中输出一个字节
public void write(int b);
 
//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。
public void write(byte[] b,int off,int len);
 
//刷新此缓冲的输出流。这迫使所有缓冲的输出字节被写出到底层输出流中。
public void flush();

4、复制文件:

public class BufferedTest {
	public static void main(String[] args) throws IOException {
		BufferedInputStream bis = new BufferedInputStream(
				      new FileInputStream("src\\IOTest\\testfile.txt"));
		BufferedOutputStream bos = new BufferedOutputStream(
					  new FileOutputStream("src\\IOTest\\bufferedCopy.txt"));
		byte[] buffer = new byte[1024*1024];
		int len = 0;
		while((len=bis.read(buffer))!=-1) {
			bos.write(buffer, 0, len);
		}
                //刷新输出流,保证数据全部写出到文件中
		bos.flush();
		bis.close();
		bos.close();
	
	}
}

      查看BufferedOutputStream的源代码,发现所谓的buffer其实就是一个byte[]。BufferedOutputStream的每一次write其实是将内容写入byte[],当buffer容量到达上限时,会触发真正的磁盘写入。而另一种触发磁盘写入的办法就是调用flush()了。