Java字节流与字符流及文件操作

Java.io知识点梳理

如果要进行所有的文件以及文件内容的开发操作,应该使用java.io包完成,而在java.io包里面一共有五个核心类和一个核心接口:

  1. 五个核心类:File、InputStream、OutputStream、Reader、Writer
  2. 一个核心接口:Serializable
    在这里插入图片描述

File类

在整个java.io包里面,File类是唯一一个与文件本身操作有关的类 ,但是不涉及到文件的具体内容,所谓的文件本身,指的是文件的创建和删除等。

几个重点掌握方法:
1.构造方法:public File(String pathname) 设置文件路径
2.普通方法:public boolean delete(); 删除文件
3.普通方法:public boolean exists()判断文件是否存在
4.普通方法:public File getParentFile();public String getParentFile();得找到父路径
5.普通方法:public Boolean mkdirs() 创建多级子目录
6普通方法:.public long length() 取得文件大小,按照字节大小返回;

例:创建目录及文件

import java.io.File;

public class TestFile02 {
	public static void main(String[] args) throws Exception{
		File file = new File("g:"+File.separator+"demo"+File.separator+"next"+File.separator+"test.txt");//设置路径
		System.out.println(file.getParent());//g:\demo\next
		if(!(file.getParentFile().exists())) {//如果父路径不存在
			file.getParentFile().mkdirs();//如果nex不存在,就创建next
		}
		if(file.exists()) {
			System.out.println("删除成功"+file.delete());
		}else {
			System.out.println(file.createNewFile());
		}
	}
}

注意:1.为什么不使用"\\"(表示转义成\)或者“\”?

1.在Windows系统里面支持的是“\”路径分隔,Linux(部署项目)下使用的是“/”路径分隔符;
解决:在File类里面提供有一个常量:public static final String separator(特殊,一般为大写的常量)

2.为什么创建文件时会有延迟?

在进行java.io操作的过程中,出现延迟情况,是因为java程序是通过JVM间接调用操作系统的文件处理函数进行文件处理操作(它不能直接操作文件),所以中间出现延迟。

字节流OutputStream

OutputStream类是一个专门进行字节数据输出的一个类,这个类定义如下

扫描二维码关注公众号,回复: 11403871 查看本文章
public abstract class OutputStream extends Object
	implements Closeable, Flushable //实现了两个接口
public interface Closeable extends AutuCloseable 
public interface  AutuCloseable 

了解一下它实现的两个接口Closeable和Flushable
在JDK1.7的时候引入了一个非常神奇的自动关闭机制,所以让Closeable又多继承了一个AutoCloseable接口,但是OutputStream类在JDk1.0的时候就提供有close()、和flush()两个操作方法,所以以上的两个接口就几乎可以忽略了。

使用OutputStream输出文件内容

OutputStream本身是属于抽象类,如果想要为抽象类进行对象的实例化操作,那么一定要使用抽象类子类,而本身要进行的是对文件的操作,所以可以使用FileOutStream子类。
在FileOutStream子类里定义的构造方法:public FileOutputStream(File file)
创建文件输出流以写入由指定的 File对象表示的文件。

在OutputStream类提供有三个输出方法:
在这里插入图片描述

**例:**输出字节数组

	public static void main(String[] args) throws Exception {
		//1.定义输出文件的路径     (资源访问到处都是异常)
		File file =new File("G:"+File.separator+"demo1"+File.separator+"OutpS.text");
		//1.此时由于目录不存在,所以文件不能输出,那么得创建目录
		if(!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		//2.使用OUtputStream和其子类进行对象实例化
		//2.此目录存在,文件不存在,利用其构造(File file)生成文件
		OutputStream output =new FileOutputStream(file,true);
		//3.要进行文件内容的输出,并将字符串变为字节数组
		String str ="你好,HelloWorld\r\n";
		byte data[]=str.getBytes();
		//4.将内容输出
		output.write(data);
		//资源操作的最后一步一定要进行关闭
		output.close();
	}

以上对内容进行了输出,并且如果此时要输出的文件不存在,那么将自动进行创建。

**例:**出指定位置(开始),指定长度,字节

public class TestOutpS03 {
	public static void main(String[] args) throws Exception {
		File file =new File("G:"+File.separator+"demo1"+File.separator+"OutpS03.text");
		if(!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		//2.此目录存在,文件不存在,利用其构造(File file)生成文件
		OutputStream output =new FileOutputStream(file);
		String str ="你好,HelloWorld!";
		byte data[]=str.getBytes();
		output.write(data,6,5);
		output.close();
	}
}

输出结果为:Hello
注意:我们这是对字节进行输出,一个中文or中文标点占用两个字节(你好,),所以我们是从“H”开始,输出5个字节后结束。

以上操作默认为覆盖内容,如要追加内容,在后面加true在这里插入图片描述
如果涉及到追加那么,那么我们就得换行,而这里的换行
为什么必须是\r加上\n?
\r是回车符
\n是换行符
Linux和Unix系统的换行是"\n",而Windows的换行并不是直接的“\n”,因为Windows不认为"\n"是换行,在文档中只是一个空格或者小黑框。所以应该是先回车,再换行。

字节流InputStream

InputStream也一个抽象类,所以如果想进行文件读取,我们的使用它的子类FileStream(具体实现接口与OutputStream差不多)

其子类构造方法:public FileOutputStream(File file)

在InputStream中定义了如下三种方法读取数据:

1.读取的单个字节:public abstract int read()
|-返回值:从输入流读取数据的下一个字节。 值字节被返回作为int范围0至255 。 如果没有字节可用,因为已经到达流的末尾,则返回值-1 。(返回值与2.3有区别)
2.将读取的数据保存在字节数组里:public int read(byte[]b) (不建议用)
|-返回值:返回读取的数据长度,已经到达流的末尾,则返回值-1 。
3.将读取的数据保存在部分字节数组里:public int read(byte[]b, int off,int len)
|-返回值:读取的部分数据的长度,已经到达流的末尾,则返回值-1 。

例:将读取的数据保存在部分字节数组里

public class TestInputS02 {
	public static void main(String[] args) throws Exception {
		File file =new File("G:"+File.separator+"demo1"+File.separator+"OutpS.text");
		if(file.exists()) {//文件存在
			//2.使用InputStream进行读取
			InputStream input =new FileInputStream(file);
			byte data[]=new byte [1024];//准备一个1024的字节数组(缓冲区)
			//将内容存到数组中,并用len接收他的长度
			int len=input.read(data);
			System.out.println(len);//接收返回值
			input.close();
			System.out.println("【"+new String(data,0,len)+"】");
		}else {
			System.out.println("文件不存在!");
		}
	}
}

这个是我们文本内容
在这里插入图片描述
输出结果:
在这里插入图片描述
可以看到这个返回值是字节长度。

例:读取的单个字节:public abstract int read()

		File file =new File("G:"+File.separator+"demo1"+File.separator+"InpS.text");
		if(file.exists()) {//文件存在
			InputStream input =new FileInputStream(file);
			byte data[]=new byte [1024];//准备一个1024的字节数组(缓冲区)
			int temp =0; //接收每次读取的字节数据
			for(int x=0;x<5;x++) {
				temp=input.read(); //只接收5个返回值
				System.out.println(temp);
			}

这是我们的文本内容
在这里插入图片描述
结果:
在这里插入图片描述
可以看到这时返回的是该字所对应的ASCII值

字符流Writer

public abstract class Writer
	 implement Closerable,Appendable,Flushable

Appendable接口定义如下:(虽然有这个接口,但我们基本上用不上,因为Writer接口本身就有write方法)
在这里插入图片描述

在Writer类里面定义有以下的输出方法(部分):

输出全部字符数组:public void write(char[] cuuf)
输出字符串:public void write(String Str)
Writer是一个抽象类,如果要想为这个类的对象实例化,应该使用FileWriterd子类(和FileOUtputStream一样提供有File构造)

例:使用Writer输出字符串
在这里插入图片描述
可以发现Writer可以作为字符串输出流,可以直接进行字符串的输出

字符流Reader

Reader是进行字符数据读取的输入流,其本身也是抽象类

在Reader类里面提供有一系列的读取内容的方法

Public int read(char [] cbuf)
表示读取的数据长度,如果已经读到结尾了返回-1
在read中没有能够返回字符串的方法

例:
在这里插入图片描述
与字节输入流相比结构几乎是一样只是数据类型byte换成char。

字节流与字符流的转换(了解)

public class InputStreamReader extends Reader	

在java.io包里面提供有两个类:InputStreamReader(Reader的子类)、OUtputStreamWriter(Writer的子类)
两个构造方法:
1.public InputStreamReader(InputStream in)
2. public InputStreamWriter(OutputStream out)
在这里插入图片描述

这种转换的意义不大,但有一种情况可能会用到(字符流方便处理中文数据)

字节流与字符流的区别?

字节流与字符流的最大的区别是:字节流直接与终端进行数据交换,而字符流需要将数据经过缓冲区处理后才可以输出。(OutputStream字节流如果没有使用close关闭数据流,结果可以正常输出,而Writer字符流没有使用close关闭数据流,那么缓冲区之中处理的内容不会被强制清空,所以不会输出数据),如果有特殊情况不能够关闭字符流,可以使用flush()方法强制清空缓冲区。

相同:使用两个流进行数据输出(输入)时,都是以字节的方式保存(读取),而在使用字符流读取的时候,实际上也是对字节数据进行读取,只不过这个转换的过程被操作系统隐藏了,在缓冲区里面机进行数据的转换。

两者如何使用?

用字节数据处理的比较多,例如:图片、视频、音乐、文字
字符流:唯一的好处是能对中文进行处理。
所以:在开发中如果要处理中文最好使用字符流,如果不是中文使用字节流(使用较多)。

猜你喜欢

转载自blog.csdn.net/BG777/article/details/107482722