[Java study notes] IO stream byte stream

table of Contents

1. Overview of IO stream

2. IO flow classification

2.1 According to the data flow

2.2 According to the data type

3. Commonly used base classes for IO streams

3.1 Abstract base class of byte stream

3.2 Abstract base class of character stream

4. Byte output stream FileOutputStream

4.1 The construction method of FileOutputStream

4.2 The way to write data in byte input stream

5. Byte input stream FileInputStream

5.1 The construction method of FileInputStream

5.2 Member methods of FileInputStream

6. Byte buffered output stream BufferedOutputStream

7. Byte buffered input stream BufferedInputStream

8. Four ways of byte stream copy MP4 and test efficiency


1. Overview of IO stream

  • IO stream is used to process data transmission between devices , such as: uploading files and downloading files
  • The operation of Java on data is through the way of streaming
  • The objects used by Java to manipulate the flow are all in the IO package

2. IO flow classification

2.1 According to the data flow

  • Input stream: read data
  • Output stream: write data

2.2 According to the data type

  • Byte stream
  • Character stream

When to choose byte stream? In which case should character stream be chosen?

  • If the file where the data is located is opened through the notepad that comes with windows and can read the content inside, use the character stream. Others use byte streams.
  • If you don’t know anything, use byte stream

3. Commonly used base classes for IO streams

3.1 Abstract base class of byte stream

  • InputStream
  • OutputStream

3.2 Abstract base class of character stream

  • Reader
  • Writer

Note: The names of subclasses derived from these four classes are all suffixed with the name of their parent class!

E.g:

  • FileInputStream, a subclass of InputStream, FileOutputStream, a subclass of OutputStream
  • FileReader, a subclass of Reader, FileWriter, a subclass of Writer

4. Byte output stream FileOutputStream

4.1 The construction method of FileOutputStream

  • FileOutputStream(File file): Create a file output stream that writes data to the file represented by the specified File object
  • FileOutputStream(String name): Create an output file stream that writes data to a file with the specified name

4.1.1 Requirements: write data "hello,io" to a file

4.1.2 What are the steps of the byte output stream?

  • Create byte output stream object
  • data input
  • Release resources

code show as below:

package cn.itcast_01;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 需求: 向一个文件中写入数据"hello,io"
 * 
 * @author HW
 */
public class FileOutputStreamDemo {
	public static void main(String[] args) {
		FileOutputStream fos = null;
		try {
			// 创建字节输出流对象
			fos = new FileOutputStream("fos.txt");
			// 写入数据
			String str = "hello,io";
			fos.write(str.getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			// 只有在fos!=null的时候,才需要释放资源,否则会报空指针异常
			if(fos!=null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

4.1.3 What exactly did the creation of the byte output stream object do?

  • Call system functions to create files
  • Create a byte output stream object fos
  • Point the byte output stream object fos to this file

4.1.4 After the data is written successfully, why close close()?

  • Let the stream object become garbage, so that it can be recycled by the garbage collector
  • Notify the system to release resources related to the file    

4.2 The way to write data in byte input stream

  • public void write(int b): write the specified byte to this file output stream
  • public void write(byte[] b): Write b.length bytes from the specified byte array to the file output stream
  • public void write(byte[] b,int off,int len): Write len bytes starting from offset off in the specified byte array to this file output stream.

4.2.1 How to realize data line break?

code show as below:

package cn.itcast_01;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *如何实现数据的换行?使用换行符\r\n
 * 
 * @author HW
 *
 */
public class FileOutputStreamDemo2 {
	public static void main(String[] args) {
		FileOutputStream fos = null;
		try {
			// 创建字节输出流对象fos
			fos = new FileOutputStream("fos.txt");
			
			// 将指定字节写入fos对象中
			fos.write(97);
			// 实现换行
			fos.write("\r\n".getBytes());
			
			// 将一个字节数组写入fos中
			byte[] b = { 97, 98, 99, 100, 101 };
			fos.write(b);
			fos.write("\r\n".getBytes());
			
			//将字节数组b的从1开始的3个字节写入fos中
			fos.write(b, 1, 3);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if(fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

4.2.2 How to implement additional writing of data?

 Use the construction method:

  • public FileOutputStream(File file, boolean append): Create a file output stream that writes data to the file represented by the specified File object. If the second parameter is true, the bytes are written to the end of the file;
package cn.itcast_02;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 如何实现数据的追加写入?
 * 
 * 使用构造方法:
 * public FileOutputStream(File file, boolean append):创建一个向指定File对象表示的文件中写入数据的文件输出流,如果第二个参数为true,则将字节写入文件末尾处;
 */
public class FileOutputStreamDemo2 {
	public static void main(String[] args) {
		// 声明字节输出流的引用
		FileOutputStream fos = null;
		try {
			// 生成一个代表字节输出流的对象,实现在末尾追加写入数据
			fos = new FileOutputStream("fos3.txt", true);
			// 调用write()方法,写入数据
			for (int x = 0; x < 10; x++) {
				fos.write(("Hello" + x).getBytes());
				// 实现数据换行
				fos.write("\r\n".getBytes());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			// 释放资源
			// 只有在fos!=null的时候,才需要释放资源,否则会报空指针异常
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

5. Byte input stream FileInputStream

5.1 The construction method of FileInputStream

  • public FileInputStream(File file)
  • public FileInputStream(String name)

5.2 Member methods of FileInputStream

  • public int read(): Read one byte at a time, if it reads to the end of the file and there is no more data, it returns -1
  • public int read(byte[] b): Read one byte array at a time, and return the number of bytes (length) actually read. If the end of the file is read and there is no more data, -1 is returned

What are the steps for byte input stream?

  • Create byte input stream object
  • Call the read() method to read the data and display the data on the console
  • Release resources

5.2.1 Read one byte at a time

  • public int read(): Read one byte at a time, if it reads to the end of the file and there is no more data, it returns -1

Requirement 1: Copy the text file with byte stream, copy the content in srcFile.txt in the current directory to destFile.txt in the current project

code show as below:

package com.hw.inputstream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * public int read():一次读取一个字节,如果读取到文件的末尾,则返回-1
 * 
 * 需求:字节流复制文本文件,把当前目录下的srcFile.txt中的内容复制到当前项目下的destFile.txt中 
 * 数据源:srcFile.txt
 * 目的地:destFile.txt
 * 
 * @author HW
 * 
 */
public class CopyFileDemo {
	public static void main(String[] args) {
		// 声明字节输入流的引用(数据源)
		FileInputStream fis = null;
		// 声明字节输出流的引用(目的地)
		FileOutputStream fos = null;

		try {
			// 生成代表字节输入流的对象
			fis = new FileInputStream("srcFile.txt");
			// 生成代表字节输出流的对象
			fos = new FileOutputStream("destFile.txt");

			// 读取数据,一次读取一个字节,如果读取到文件的末尾,则返回-1
			int b = 0;
			while ((b = fis.read()) != -1) {
				fos.write(b);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Requirement 2: Copy D:\\develop\\images\\lover.jpg to sunset.jpg in the current project directory

code show as below:

package com.hw.inputstream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * public int read():一次读取一个字节的数据,如果读取到文件的末尾,则返回-1
 * 
 * 需求:把D:\\develop\\images\\lover.jpg复制到当前项目目录下的sunset.jpg中
 * 
 * @author HW
 * 
 */
public class CopyImageDemo {
	public static void main(String[] args) {
		// 声明字节输入流FileInputStream的引用
		FileInputStream fis = null;
		// 声明字节输出流FileOutputStream的引用
		FileOutputStream fos = null;

		try {
			// 生成代表字节输入流的对象
			fis = new FileInputStream("D:\\develop\\images\\lover.jpg");
			// 生成代表字节输出流 的对象
			fos = new FileOutputStream("sunset.jpg");

			// 复制图片
			// 一次读取一个字节的数据,如果读取到文件的末尾,则返回-1
			int b = 0;
			while ((b = fis.read()) != -1) {
				fos.write(b);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Requirement 3: Copy D:\\develop\\images\\computer base.avi to video.avi in ​​the current project directory

code show as below:

package com.hw.inputstream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * public int read():一次读取一个字节的数据,如果读取到文件的末尾,则返回-1
 * 
 * 需求:把D:\\develop\\images\\计算机基础.avi复制到当前项目目录下的video.avi中
 * 
 * @author HW
 * 
 */
public class CopyVideoDemo {
	public static void main(String[] args) {
		// 声明字节输入流的引用
		FileInputStream fis = null;
		// 声明字节输出流的引用
		FileOutputStream fos = null;

		try {
			// 生成代表字节输入流的对象
			fis = new FileInputStream("D:\\develop\\images\\计算机基础.avi");
			// 生成代表字节输出流的对象
			fos = new FileOutputStream("video.avi");

			// 复制视频
			// 一次读取一个字节的数据
			int b = 0;
			while ((b = fis.read()) != -1) {
				fos.write(b);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}

5.2.2 Read one byte array at a time

  • public int read(byte[] b): Read one byte array at a time, and return the number of bytes (length) actually read. If the end of the file is read and there is no more data, -1 is returned

Requirement 1: Copy the content in D:\\develop\\users.xml to E:\\student.xml in the current project directory

code show as below:

package com.hw.inputstream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * public int read(byte[] b):一次读取一个字节数组的数据,返回的是实际读取的字节的长度,如果读取到文件的末尾而没有更多的数据,则返回-1
 * 
 * 需求:把D:\\develop\\users.xml中的内容复制到当前项目目录下的E:\\student.xml中
 * 
 * @author HW
 */
public class CopyFileDemo {
	public static void main(String[] args) {
		// 声明字节输入流的引用
		FileInputStream fis = null;
		// 声明字节输出流的引用
		FileOutputStream fos = null;
		File file = null;

		try {
			// 生成代表字节输入流的对象
			fis = new FileInputStream("D:\\develop\\users.xml");

			// 生成代表字节输出流的对象
			fos = new FileOutputStream("E:\\student.xml");

			// 复制数据,一次读取一个字节数组的数据
			// 生成一个byte类型的数组
			byte[] b = new byte[1024];
			// 实际读取的字节长度
			int len = 0;
			while ((len = fis.read(b)) != -1) {
				fos.write(b, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Requirement 2: Copy D:\\develop\\images\\computer base.avi to video.avi in ​​the current project directory

code show as below:

package com.hw.inputstream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * public int read(byte[] b):一次读取一个字节数组的数据,返回的是实际读取的字节长度,如果读取到文件的末尾,则返回-1
 * 
 * 需求:把D:\\develop\\images\\计算机基础.avi复制到当前项目目录下的video.avi中
 * 
 * @author HW
 */
public class CopyVideoDemo {
	public static void main(String[] args) {
		// 声明字节输入流的引用
		FileInputStream fis = null;
		// 声明字节输出流的引用
		FileOutputStream fos = null;

		try {
			// 生成代表字节输入流的对象
			fis = new FileInputStream("D:\\develop\\images\\计算机基础.avi");
			// 生成代表字节输出流的对象
			fos = new FileOutputStream("video.avi");

			// 复制视频,一次读取一个字节数组的数据
			// 生成一个byte类型的数组
			byte[] b = new byte[1024];
			// 实际读取的字节长度
			int len = 0;
			while ((len = fis.read(b)) != -1) {
				fos.write(b, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

The speed of byte stream reading and writing an array at a time is obviously much faster than the speed of reading and writing one byte at a time. This is the effect of adding a buffer such as an array. When java itself is designed, this design idea is also taken into account , so Byte buffer stream is provided!

6. Byte buffered output stream BufferedOutputStream

For specific usage, refer to the following code:

package com.hw.inputstream;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 字节缓冲输出流BufferedOutputStream
 * 
 * @author HW
 * 
 */
public class BufferedOutputStreamDemo {
	public static void main(String[] args) {
		// 声明BufferedOutputStream引用
		BufferedOutputStream bos = null;

		try {
			// 创建字节缓冲输出流对象
			bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
			// 写入数据
			bos.write("hello,bos!".getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

7. Byte buffered input stream BufferedInputStream

For specific usage, refer to the following code:

package com.hw.inputstream;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 字节缓冲输入流BufferedInputStream
 * 
 * @author HW
 * 
 */
public class BufferedInputStreamDemo {
	public static void main(String[] args) {
		// 声明BufferedInputStream引用
		BufferedInputStream bis = null;

		try {
			// 创建字节缓冲输入流对象
			bis = new BufferedInputStream(new FileInputStream("bis.txt"));

			// 读取数据,一次读取一个字节数组
			// 生成一个byte类型的字节数组
			byte[] bytes = new byte[1024];
			// 实际读取的字节长度
			int len = 0;
			while ((len = bis.read(bytes)) != -1) {
				// 生成String类型的对象
				String str = new String(bytes, 0, len);
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

8. Four ways of byte stream copy MP4 and test efficiency

Requirement: Copy D:\\develop\\images\\computer base.avi to video.avi in ​​the current project directory

Byte stream copy files in four ways: FileInputStream&FileOutputStream, BufferedInputStream&BufferedOutputStream

  • Basic byte stream reads and writes one byte at a time
  • Basic byte stream reads and writes one byte array at a time
  • Efficient byte stream reads and writes one byte at a time
  • Efficient byte stream reads and writes one byte array at a time

code show as below:

package com.hw.inputstream;

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

/**
 * 需求:把D:\\develop\\images\\计算机基础.avi复制到当前项目目录下的video.avi中
 * 
 * 字节流四种方式复制文件: 
 * FileInputStream & FileOutputStream 
 * 1.基本字节流一次读写一个字节,共耗时:46788毫秒
 * 2.基本字节流一次读写一个字节数组,共耗时:54毫秒
 * 
 * BufferedInputStream & BufferedOutputStream 
 * 3.高效字节流一次读写一个字节,共耗时:156毫秒
 * 4.高效字节流一次读写一个字节数组,共耗时:12毫秒
 * 
 * @author HW
 * 
 */
public class CopyVideoTest {
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		// method1("D:\\develop\\images\\计算机基础.avi", "video.avi");
		// method2("D:\\develop\\images\\计算机基础.avi", "video.avi");
		// method3("D:\\develop\\images\\计算机基础.avi", "video.avi");
		method4("D:\\develop\\images\\计算机基础.avi", "video.avi");
		long end = System.currentTimeMillis();
		System.out.println("共耗时:" + (end - start) + "毫秒");
	}
	
	// 高效字节流一次读取一个字节数组
	private static void method4(String srcStr, String destStr) {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		
		try {
			// 创建字节缓冲输入/输出流对象
			bis = new BufferedInputStream(new FileInputStream(srcStr));
			bos = new BufferedOutputStream(new FileOutputStream(destStr));

			// 一次读取一个字节数组
			// 生成一个byte类型的数组
			byte[] bytes = new byte[1024];
			// 实际读取的字节长度
			int len = 0;
			while ((len = bis.read(bytes)) != -1) {
				bos.write(bytes);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// 高效字节流一次读取一个字节
	private static void method3(String srcStr, String destStr) {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		
		try {
			// 创建字节缓冲输入/输出流对象
			bis = new BufferedInputStream(new FileInputStream(srcStr));
			bos = new BufferedOutputStream(new FileOutputStream(destStr));
			
			// 一次读取一个字节
			int  b = 0;
			while((b = bis.read()) != -1) {
				bos.write(b);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// 基本字节流一次读写一个字节数组
	private static void method2(String srcStr, String destStr) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		try {
			// 创建字节输入/输出流对象
			fis = new FileInputStream(srcStr);
			fos = new FileOutputStream(destStr);

			// 一次读取一个字节数组
			// 生成一个byte类型的数组
			byte[] bytes = new byte[1024];
			// 实际读取的字节长度
			int len = 0;
			while ((len = fis.read(bytes)) != -1) {
				fos.write(bytes);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// 基本字节流一次读写一个字节
	private static void method1(String srcStr, String destStr) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		try {
			// 创建字节输入/输出流对象
			fis = new FileInputStream(srcStr);
			fos = new FileOutputStream(destStr);
			
			// 读取数据,一次读取一个字节,如果读取到文件的末尾,则返回-1
			int b = 0;
			while ((b = fis.read()) != -1) {
				fos.write(b);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 释放资源
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 

Guess you like

Origin blog.csdn.net/weixin_44679832/article/details/105393517