java IO——字节流与字符流

梦想的初衷 提交于 2019-12-14 03:07:09

本节目标:

1.掌握流的概念

2.掌握字节流与字符流的作用

3.掌握文件的标准操作步骤

4.掌握字节与字符的操作的区别

1. 流

在程序中,所有的数据都是以流的方式进行传输和保存的,程序需要数据的时候需要输入流读取数据,而当程序需要将数据保存起来的时候,需要输出流完成。如下图所示。
在这里插入图片描述

2. 字节流与字符流

在java.io 包中,操作文件内容的主要有两大类:字节流、字符流。两类都分为输入和输出操作。字节流输出数据主要是使用OutputStream完成,输入使用InputStream完成;字符流输出数据主要是使用Writer类完成,输出数据使用Reader类完成。

以文件操作为例,操作流程为:

1)使用File类打开一个文件

2)通过字节流或字符流的子类,指定输出的位置

3)进行读/写操作

4)关闭输入/输出流

注意:使用File类时注意分隔符问题;以上四个类都是抽象类;IO操作属于资源操作,对于资源操作,操作完后必须关闭,否则可能会出现未知的错误。

3.字节流

常用的字节流总结,参考博文,点击这里
字节流主要是操作byte类型数据,以byte数组为准,主要操作类时字节输入流InputStream、字节输出流OutputStream.

3.1 字节输出流-OutputStream

OutputStream是整个io包中字节输出流的最大父类,此类定义如下:

public abstract class OutputStream extends Object implements Closeable, Flushable

可以发现,此类是一个抽象类,如果要使用此类,需要通过子类实例化对象,如果操作的是一个文件,可以使用FileOutputStream类实例化。

FileOutputStream(File file)

      创建一个向指定 File 对象表示的文件中写入数据的文件输出流,覆盖原先文件内容。

FileOutputStream(File file, boolean append)

      创建一个向指定 File 对象表示的文件中写入数据的文件输出流,追加内容。

在这里插入图片描述

public class OutputStreamDemo1 {
public static void main(String[] args) throws IOException {
	//1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	//2.实例化输出流对象
	OutputStream out = new FileOutputStream(f);
	//3.写操作
	String str = "Hello World!";
	byte[] b = str.getBytes();
	out.write(b);
	//4.关闭流
	out.close(); 
public class OutputStreamDemo2 {
public static void main(String[] args) throws IOException {
		//1.使用File类找到一个文件
		File f = new File("f:" + File.separator + "test.txt");
		//2.实例化输出流对象
		OutputStream out = new FileOutputStream(f);
		//3.写操作
		String str = "Hello World!!";
		byte[] b = str.getBytes();
		for (int i = 0; i < b.length; i++) {//采用循环方式写入
		out.write(b[i]);//每次只写一个字节
		}
		//4.关闭流
		out.close();
		}

}

在文件中在追加数据,且换行追加:

public class OutputStreamDemo2 {
	public static void main(String[] args) throws IOException {
	//1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	//2.实例化输出流对象
	OutputStream out = new FileOutputStream(f,true);
	//3.写操作
	String str = "\r\nHello World!!";
	byte[] b = str.getBytes();
	for (int i = 0; i < b.length; i++) {//采用循环方式写入
	out.write(b[i]);//每次只写一个字节
	}
	//4.关闭流
	out.close();
	}
}

3.2 字节输入流-InputStream

InputStream可以将文件中的数据读取出来,该类的定义为:

public abstract class InputStream extends Object implements Closeable

子类实例化使用FileInputStream

常用的方法如下:

在这里插入图片描述

public class InputStreamDemo1 {
public static void main(String[] args) throws IOException {
	// 1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	// 2.实例化输入流对象
	InputStream input = new FileInputStream(f);
	// 3.读操作
	byte[] b = new byte[1024];  //所有的内容读到字节数组中
	input.read(b);//读取内容
	// 4.关闭流
	input.close();
	System.out.println("文件内容:" + new String(b) );
	}

}

内容输出时含有过多浪费的空间

public class InputStreamDemo2 {
public static void main(String[] args) throws IOException {
// 1.使用File类找到一个文件
File f = new File("f:" + File.separator + "test.txt");
// 2.实例化输入流对象
InputStream input = new FileInputStream(f);
// 3.读操作
byte[] b = new byte[1024];  //所有的内容读到字节数组中
int lenth = input.read(b);//读取内容
// 4.关闭流
input.close();
System.out.println("文件内容:" + new String(b,0,lenth) );
}

}

指定了字节数组空间,可能会造成空间浪费。

public class InputStreamDemo1 {
	public static void main(String[] args) throws IOException {
	// 1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	// 2.实例化输入流对象
	InputStream input = new FileInputStream(f);
	// 3.读操作
	byte[] b = new byte[(int) f.length()];  //数组大小由文件大小决定
	int lenth = input.read(b);//读取内容
	// 4.关闭流
	input.close();
	System.out.println("文件内容:" + new String(b) );
	}
}

如果按单个字节读取的话:

public class InputStreamDemo1 {
	public static void main(String[] args) throws IOException {
	// 1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	// 2.实例化输入流对象
	InputStream input = new FileInputStream(f);
	// 3.读操作
	byte[] b = new byte[(int) f.length()]; //数组大小由文件大小决定
	for (int i = 0; i < b.length; i++) {
	b[i] = (byte) input.read();
	}
	// 4.关闭流
	input.close();
	System.out.println("文件内容:" + new String(b) );
	}

}

当不知道文件大小时,以读取的数据是否为-1作为读完的标志。

public class InputStreamDemo1 {
public static void main(String[] args) throws IOException {
	// 1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	// 2.实例化输入流对象
	InputStream input = new FileInputStream(f);
	// 3.读操作
	byte[] b = new byte[(int) f.length()];  //数组大小由文件大小决定
	int temp = 0;
	int len = 0;//接收每一个读取进来的数据
	while((temp = input.read()) != -1){
	//如果文件还有内容
	b[len] = (byte) temp;
	len++;
	}
	// 4.关闭流
	input.close();
	System.out.println("文件内容:" + new String(b));
	}
}

4. 字符流

在程序中,一个字符等于两个字节,针对字符操作的类是字符输出流Writer和字符输入流Reader

4.1 字符输出流-Writer

public abstract class Writer extends Object implements Closeable, Flushable, Appendable
在这里插入图片描述

public class WriterDemo1 {
	public static void main(String[] args) throws IOException {
	//1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	//2.实例化输出流对象
	Writer out = new FileWriter(f);
	//3.写操作
	String str = "Hello World!!";
	out.write(str);
	//4.关闭流
	out.close();
	}

}

如果要追加内容,且内容换行追加:

public class WriterDemo1 {
	public static void main(String[] args) throws IOException {
	//1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	//2.实例化输出流对象
	Writer out = new FileWriter(f,true);
	//3.写操作
	String str = "\r\nHello World!!";
	out.write(str);
	//4.关闭流
	out.close();
	}
}

4.2 字符输入流-Reader

public abstract class Reader extends Object implements Closeable, Readable
在这里插入图片描述

public class ReaderDemo1 {
	public static void main(String[] args) throws IOException {
	// 1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	// 2.实例化输入流对象
	Reader input = new FileReader(f);
	// 3.读操作
	char[] c = new char[1024];
	int len = input.read(c);
	// 4.关闭流
	input.close();
	System.out.println("文件内容:" + new String(c,0,len));
	}
}
public class ReaderDemo1 {
public static void main(String[] args) throws IOException {
	// 1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	// 2.实例化输入流对象
	Reader input = new FileReader(f);
	// 3.读操作
	char[] c = new char[1024]; 
	int temp = 0;
	int len = 0;//接收每一个读取进来的数据
	while((temp = input.read()) != -1){
	//如果文件还有内容
	c[len] = (char) temp;
	len++;
	}
	// 4.关闭流
	input.close();
	System.out.println("文件内容:" + new String(c));
	}

}

5.字节流与字符流的区别

字节流在操作的时候本身不用缓存区的,是与文件直接对接的;而字符流操作时需要缓冲区。

在这里插入图片描述

使用字节流时,即使流没有关闭,最终也可以输出到文件;

使用字符流时,所有的内容保存在缓冲区,流关闭时 会强制性的将缓冲区内容写到文件中,如果没有关闭流,文件中就不会有内容输出。

public class WriterDemo1 {
public static void main(String[] args) throws IOException {
	//1.使用File类找到一个文件
	File f = new File("f:" + File.separator + "test.txt");
	//2.实例化输出流对象
	Writer out = new FileWriter(f,true);
	//3.写操作
	String str = "\r\nHello World!!";
	out.write(str);
	out.flush();//刷新缓冲区内容到文件中
	//4.关闭流
	//	out.close();
	}

}

6.范例:文件拷贝

class Copy{
public static void main(String[] args) throws IOException{
	if(args.length != 2){
	System.out.println("输入的参数不正确!");
	System.exit(1);
	}
	File f1 = new File(args[0]);
	File f2 = new File(args[1]);
	InputStream input = new FileInputStream(f1);
	OutputStream out = new FileOutputStream(f2);
	if (input != null && out != null) {
	int temp = 0;
	while ((temp = input.read()) != -1) {
	out.write(temp);
	}
	System.out.println("拷贝完成!");
	input.close();
	out.close();
	}
	}

}

7.总结

  1. 流的概念

  2. 字节流与字符流操作文件的基本步骤

3.字节流与字符流的区别

字节流:没有使用缓冲区

字符流:使用缓冲区

4.边读边写的方式在以后开发中非常有用
————————————————
版权声明:本文为CSDN博主「Devin01213」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ym01213/article/details/79702220

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!