I/O流基础

发布时间:2024年01月06日

1.输入/输出流

流是一组有序的数据序列,根据操作的类型,可以分为输入流和输出流两种。
Java定义的输入输出类被放在java.io包中
所有的输入流类都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类
而所有输出流都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类

1.1输入流

InputStream类是字节输入流的抽象类,它是所有字节输入流的父类。
InputStream类的具体层次结构如图

该类中所有方法遇到错误时都会引发IOException异常,下面是该类方法中的简要说明:
·read():从输入流中读取数据的下一个字节。返回0~255的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回值为1
·read(byte[] b):从输入流中读入一定长度的字节,并以证书的形式返回字节数
·mark(int readlimit):在输入流的当前位置放置一个标记,readlimit参数告知此输入流在标记位置失效前允许读取的字节数
·reset():将输入指针返回到当前所做的标记处
·skip(long n):跳过输入流上的n个字节并返回实际跳过的字节数
·markSupported():如果当前流支持mark()/reset()操作就返回true
·close():关闭此输入流并释放与该留关联所有的系统资源
并不是所有的InputStream类的子类都支持InputStream类中定义的所有方法,如skip(),mark(),reset()等方法只对某些子类有用

InputStream类是用来处理字节的,并不适合处理字符文本。Reader类是可以专门处理字符文本的类,但是Reader类并不是InputStream类的替换者,只是在处理字符串的时候简化了编程。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。
Reader类的层次结构

1.2输出流

OutputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。
层次结构如图

OutputStream类中的所有方法均返回void,在遇到错误时会引发IOException异常。下面是对OutputStream类中的一些方法的简要说明:
write(int b):将指定的字节写入此输出流。
write(byte[] b)方法:将b个字节从指定的byte数组写入此输出流。
write(byte[] b,int off,int len)方法:将指定byte数组中从偏移量off开始的len个字节写入此输出流。
flush()方法:彻底完成输出并清空缓存区。 
close()方法:关闭输出流。

Writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类
在这里插入图片描述

2.File类

File类是java.io包中唯一代表磁盘文件本身的类。File类定义了一些与平台无关的方法开操作文件,可以通过调用File类的方法,实现创建、删除、重命名文件等操作。
File类的对象主要用来获取文件本身的一些信息,如文件所在目录,文件的长度、文件读写权限等。数据流可以将数据写入文件中。

2.1文件的创建与删除

通常使用以下三种方法来创建文件对象
1.File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建一个新File实例:
	new File(String pathname),
其中 pathname代表包含文件名的路径名。例如:
   File file = new File("D:/test.txt");
2.File(String parent,String child):该构造方法根据定义的父路径和子路径字符串(包含文件名)创建一个新的File对象,语法如下:
    new File(String parent,String child)
      ·parent:父路径字符串,如D:/或D:/doc
      ·child:子路径字符串,如letter.txt
3.File(File f,String child):该构造方法根据f抽象路径名和child路径名字符串创建一个新File实例。语法如下:
    new File(File f,String child)
	  ·f:父路径对象,如D:/doc/
	  ·child:子路径字符串,如letter.txt
注意:如果使用File类创建文件对象后,如果该目录中没有此文件,会自动调用creatNewFile()方法创建一个文件,如果存在,可通过文件对象的delete()方法将其删除

2.2获取文件信息

file类提供了很多方法获取文件本身的信息

在这里插入图片描述

import java.io.File;
public class FileDemo{
	public static void main(String[] args){
		File file = new File("D:\\word.txt"); //创建文件对象
		if(file.exists()){			//如果文件存在
			String name = file.getName();//获取文件名称
			long length = file.length(); //获取文件长度
			boolean hidden = file.isHidder();//判断文件是否是隐藏文件
			System.out.println("文件名称是:"+name);
			System.out.println("文件长度:"+length);
			System.out.println("该文件是隐藏文件吗:"+hidden);
		}
		else{
			System.out.println("文件不存在");
		}	
	}
}

3.文件输入/输出流

程序运行期间,大部分数据都在内存中进行操作,当程序结束或者关闭时,这些数据将消失。如果需要将数据永久保存,可使用文件输入/输出流与指定的文件建立连接,将需要的数据永久保存到文件中。

3.1FileInputStream与FileOutputStream类

FileInputStream类与FileOutputStream类都用来操作磁盘文件。
如果用户的文件读取需求比较简单,则可以使用FileInputStream类,该类继承自InputStream类。
FileOutStream类与FileInputStream类对应,提供了基本的文件写入能力。

FileInputStream类常用的构造方法如下:
	FileInputStream(String name):用给定的文件名name创建一个FileInputStream对象
	FileInputStream(File file):用File对象创建FileInputStream对象。允许在把文件连接输入流之前对文件做进一步分析。
FileOutputStream类有与FileInputStream类相同的参数构造方法,创建一个FileOutputStream对象时,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件,下面实例就是使用FileInputStream类与FileOutputStream类实现文件的读取与写入功能。
/*向文本文件中写入内容,再读取出来。
使用FileOutputStream类和FileInputStream类,向D盘根目录的word.txt文件中写入一句话,然后再读取出来输出在控制台上*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStreaml
import java.io.IOException;

public class FileStreamDemo{
	public static void main(String[] args){
		File file = new File("D:\\word.txt");
		try{
			FileOutputStream out = new FileOutputStream(file);  //创建输出流
			byte buy[] = "我有一个文件".getBytes();  //写入内容的字节数组
			out.wirte(buy);
			out.close();
		}catch(IOException e){
			e.printStackTrace();
		}
		try{
			FileInputStream in = new FileInputStream(file);   //创建输入流
			byte byt[] = new byte[1024];  //缓存字节数组
			int len = in.read(byt);   //将文件信息读入缓存数组中
			System.out.println("文件中的信息是:"+new String(byt,0,len));  //将字节转为字符串输出
			in.close();   //关闭流
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}
/*程序运行后会在D盘创建一个word.txt文件并且写入一行文字,并且会在控制台输出“我有一个文件”的信息*/

3.2FileReader和FileWriter类

因为汉字在文件中占两个字节,使用上面的两个字节流类可能会造成乱码,所以使用FileReader和FileWriter。
FileReader类顺序读取文件,只要不关闭流,每次调用read()方法就顺序的读取源中其余的内容,知道源的末尾或流关闭。
/*使用字符流读写文本文件:使用FileWriter类和FileReader类,向D盘根目录的word.txt文件中写一句话,再输出到控制台上*/
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public calss FileReaderDemo{
	public static void main(String[] args){
		File file = new File("D:\\\word.txt");//创建文件对象
		try{
			FileWriter fw = new FileWriter(file);   //创建字符输出流
			String word = "这是另外一个文件";  //写入的字符串
			fw.write(word);		 //将字符串写入文件中
			fw.close();
		}catch(IOException e){
			e.printStackTrace();
		}
		try{
			FileReader fr = new FileReader(file);
			char ch[] = new char[1024];  //缓存字符数组
			int len = fr.read(ch);    //将文件中的字符读入缓存数组中
			System.out.println("文件中的信息是:"+new String(ch,0,len));    //将字符转为字符串输出
			fr.close();			 
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

4.带缓存的输入/输出流

缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区,使得在流上执行skip(),mark(),reset()方法都成为可能

4.1BufferedInputStream与BufferedOutputStream类

这两个类可以对所有的InputStrea类进行带缓存区的包装以达到性能的优化,其有两个构造方法:
	BufferedInputStream(InputStream in)
	BufferedInputStream(InputStream in,int size)
	第一种形式的构造方法创建了一个有32个字节的缓存区;
	第二个构造方法按照指定的大小来创建缓存区。
一个最优的缓存区的大小,取决于它所在的操作系统、可用的内存空间以及机器配置。从构造方法可以看出,BufferedInputStream对象位于InputStream类对象之后

BufferedInputStream读取文件过程

使用BufferedOutputStream类输出信息和仅用OutputStream类输出信息完全一样,只不过BufferedPutputStream有一个flush()方法来将缓存区的数据强制输出完。它有两个构造方法:
	BufferedOutputStream(OutputStream in):创建一个有32个字节的缓存区
	BufferedPutputStream(OutputStream in,int size):以指定大小来创建缓存区
注意:flush()方法就是用于即使在缓存区没有慢的情况下,也将缓存区的内容强制写入外设,习惯上成这个过程为刷新。flush()方法只对使用缓存区的OutputStream类的子类有效,当调用close()方法时,系统在关闭流之前,也会将缓存区的信息刷新到磁盘文件中。

4.2BufferedReader和BufferedWriter类

BufferedReader类与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并能够以行为单位进行输出/输入、

BufferedReader类读取文件的过程

BufferedReader类常用的方法如下:
	read():读取单个字符
	readLine():读取一个文本行,并将其返回为字符串。若无数据刻度,则返回null
BufferedWriter类中的方法都返回void,常用的如下:
	flush():刷新该流的缓存
	newLine():写入一个行分隔符
在使用BufferedWriter类的Writer()方法时,数据并没有立即被写入输出流,而是首先进入缓存区中,如果想立刻将缓存区中的数据写入输出流,一定要调用flush()方法。
/*使用缓冲流读写文本文件、使用BufferedReader和BufferedWriter类,向D盘根目录的word.txt文件中写入多行内容,然后再读取出来输出在控制台上*/
public class BufferedDemo{
	public static void main(String[] args){
		String content[] = {"你好","佛i啊很多事","时时发啊哈东"};
		File file = new File("D:\\word.txt");
		try{
			FileWriter fw = new FileWriter(file); //文件字符输出流
			BufferedWriter bw = new BufferedWriter(fw);    //缓冲输出流
			for(int k=0;k<content.length;k++){
				bw.wirter(content[k]);   //写入字符串
				bw.newLine(); //写入一个换行符
			}
			bw.close();
			fw.close();
		}catch(IOException e){
			e.printStackTrace();
		}
		try{
			FileReader fr = new FileReader(file);
			BufferedReader br = new BufferedReader(fr);
			String tmp = null;//作为缓冲的临时字符串
			int i =1;	//行数
			while((tmp = br.readLine()!=null)){
				System.out.println("第"+i+"行:"+tmp);
				i++;
			}
			br.close();
			fr.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

5.数据输入/输出流

DataInputStream类与DataOutputStream类允许程序以与机器无关的方式从底层输入流中读取基本的Java数据类型。
也就是说,当读取一个数据时,不必再关心这个数值是哪种字节。DataInputStream类与DataOutputStream类的构造方法如下:
	DataInputStream(InputStream in):使用指定的基础InputStream对象创建DataInputStream对象。
	DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流。

DataOutputStream类提供了将字符串,double数据、int数据、boolean数据写入文件的方法。其中将字符串写入文件的方法有3中,分别是:
	writeBytes(String s)、writeChars(String s)、writeUTF(String s)
因为Java中的字符是Unicode编码,是双字节的,wirteBytes()方法之色将字符串中的每一个字符的低字节内容写入目标设备中。
	writerChars()方法将字符串中的每一个字符的两个字节的内容都写到目标设备中;
	writeUTF()方法将字符串按照UFT编码后的字节长度写入目标设备,然后才是每一个字节的UTF编码。
DataInputStream类只提供了一个readUTF()方法返回字符串。因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道字符串的长度,就无法知道读取到什么位置才是这个字符串的结束。DataOutputStream类中只有writeUTF()方法向目标设备中写入字符串的长度,所以也能准确的读回写入字符串
/*使用数据流读写文本文件:分别通过DataOutputStream类的writeUTF()、writeDouble()、writeInt()、writeBoolean()方法向指定的word.txt文件中写入不同类型的数据,并且通过DataInputStream类的相应方法将写入的数据输出到控制台上。*/
import java.io.*;
public class FataSteamDemo{
	File file = new File("D:\\word.txt");
	try{
		//创建FileOutputStream对象,指定要向其中写入数据的文件
		FileOutputStream fos = new FileOutputStream();
		//创建DataOutputStream对象,用来向文件
		DataOutputStream dos = new DataOutputStream(fos);
		dos.writeUTF("使用writeUTF方法写入数据");//将字符串写入文件
		dos.writeDouble(19.8);
		dos.writeInt(192);
		dos.writeBoolean(ture);
		dos.close();
		fos.close();
	
		//创建FileInputStream对象,指定要从中读取数据的文件
		FileInputStream fis = new FileInputStream(file);
		DataInputStream dis = new DataInputStream(fis);
		System.out.println("readUTF方法读取数据:"+dis.readUTF());     //读取字符串
		System.out.println("readDouble方法读取数据:"+dis.readDouble());
		System.out.println("readInt方法读取数据:"+dis.readInt());    
		System.out.println("readBoolean方法读取数据:"+dis.readBoolean());    
		dis.close();
		fis.close(); 
	}catch(IOException e){
		e.printStackTrace();
	}
}
文章来源:https://blog.csdn.net/weixin_45024631/article/details/135125372
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。