第十五章 I/O(输入输出)

输入/输出流

       流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流两种。I/O流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。

       Java有数据流处理输入/输出模式,程序从指向源的输入流中读取源中的数据,源可以是文件、网络、压缩包或其他数据源。

       输出流的指向是数据要达到的目的地,程序通过向输出流中写入数据把信息传递到目的地。输出流的目标可以是文件、网络、压缩包、控制台和其他数据输出目标。

 输入流

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

该类中所有方法遇到错误时都会引发IOException 异常。下面是对该类中的一些方法的简要说明:

  •  read()方法: 从输入流中读取数据的下一个字节。返回 0~255 的 nt 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值为-1。
  • read(byte[] b): 从输入流中读入一定长度的字节,并以整数的形式返回字节数。
  • mark(int readlimit)方法: 在输入流的当前位置放置一个标记,readlimit 参数告知此输入流在标记位置失效之前允许读取的字节数。
  • reset0方法:将输入指针返回到当前所做的标记处。
  • skip(longn)方法:跳过输入流上的n个字节并返回实际跳过的字节数。
  • markSupported()方法:如果当前流支持mark0/reset0操作就返回 true。
  •  close 方法:关闭此输入流并释放与该流关联的所有系统资源。

Java 中的字符是 Unicode 编码,是双字节的。InputStream 类是用来处理字节的,并不适合处符文本。Java 为字符文本的输入专门提供了一套单独的类即Reader 类,但 Reader 类并不是 mpuStuea类的替换者,只是在处理字符串时简化了编程。Reader 类是字符输入流的抽象类,所有字符入流实现都是它的子类。Reader 类的具体层次结构如图15.4 所示。

 输出流

OutputStream 类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类OuputSteam类的具体层次如图 15.5 所示。

 OutputStream 类中的所有方法均返回 void,在遇到错误时会引发 10Exception 异常。下面是对OutputStream类中的一些方法的简题说明:

  • write(int b)方法:将指定的字节写入此输出流。
  • write(byte[] b)方法:将 b个字节从指定的 byte 数组写入此输出流。
  • write(byte[] b,int off int len)方法:将指定 byte 数组中从偏移量off开始的 len 个字节写入此输出流。
  • nush()方法:彻底完成输出并清空缓存区。
  • elose()方法:关闭输出流。

 Writer 类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。Writer 类的层次结构如图 15.6 所示。

 File 类

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

文件的创建与删除

可以使用 File 类创建一个文件对象。通常使用以下 3 种构造方法来创建文件对象。

1.File(String pathname)

该构造方法通过将给定的路径名字符串转换为抽象路径名来创建一个新 File 实例。语法如下:

new File(String pathname)

其中,pathname 代表路径名称 (包含文件名)。例如:

File file = new File("d:/1.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

案例代码:

package io.file;

import java.io.File;
 
public class FileT {
 
	public static void main(String[] args) {
	File file=new File("C:\\T\\word.txt");//创建文件对象
	if(file.exists()) {//如果文件存在
		file.delete();//将文件删除
		System.out.println("文件已删除");
	}else{//如果文件不存在
		try {//try语句块捕捉可能出现的异常
			file.createNewFile();//创建该文件
			System.out.println("文件已创建");
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	}
}

运行结果:

如果D盘没有word.txt文件,输出内容:文件已创建

如果D盘有word.txt文件,输出内容:文件已删除

获取文件信息

案例代码:

package io.file;

import java.io.File;

public class FileTest {

	public static void main(String[] args) {
				File file=new File("C:\\T\\word.txt");//创建文件对象
				if(file.exists()) {			//如果该文件存在
					String name=file.getName();
					long length=file.length();
					boolean hidden=file.isHidden();
					System.out.println("文件名称:"+name);
					System.out.println("文件长度是:"+length);
					System.out.println("该文件是隐藏文件吗?"+hidden);
					file.delete();			//将文件删除
					System.out.println("文件已删除");
				}else {							//如果文件不存在
					try {						//try语句块捕捉可能出现的异常
						file.createNewFile();	//创建该文件
						System.out.println("文件已创建");
					}catch(Exception e) {
						e.printStackTrace();
					}
				}

			}

		

运行结果:

package io.file;

import java.io.File;
public class FileTe {//创建类
	public static void main(String[] args) {//主方法
		File file=new File("C:\\Users\\czl21\\Documents\\咖啡海报素材");//创建对象
		printAllFile(file);
	}
	public static void printAllFile(File foldersPc) {
		for(File fileEntry:foldersPc.listFiles()) {
			if(fileEntry.isDirectory()) {
			System.out.println("--------"+fileEntry.getName()+"--------");
			printAllFile(fileEntry);
		}else {
			System.out.println(fileEntry.getName());
		}
	}
}
}

运行结果:

文件输入/输出流 

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

FileInputStream 类与 FileOutputStream 类 

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

FileInputStream 类常用的构造方法如下:

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

第一个构造方法使用给定的文件名 name 创建一个 FileInputStream 对象,第二个构造方法使用 File对象创建 FileInputStream 对象。

FileOutputStream 类有与 FileInputStream 类相同的参数构造方法,创建一个 FileOutputStream 对象村,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件。

 

package io.file;

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

public class Filee {

	public static void main(String[] args) throws IOException {
		File file=new File("C:\\T\\word.txt");//创建文件对象
		//输出字节流
		FileOutputStream out = new FileOutputStream(file);
		byte[] by = "你好".getBytes();//写入内容的字节数组
		out.write(by);//将字节写入文件中
		out.close();//关闭流

		//输入字节流
		FileInputStream in = new FileInputStream(file);
		byte[] by1 = new byte[1024];
		int len = in.read(by1);//将文件信息读入缓存数组中
		System.out.println(new String(by1,0,len));//将字节转为字符串输出
		in.close();//关闭流
	}

}

运行结果:

 

FileReader 和FileWriter 类

使用 FileOutputStream 类向文件中写入数据与使用 FileInputStream 类从文件中将内容读出来,都在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占用两个字节如果使用字节流,读取不好可能会出现乱码现象,此时采用字符流 FileReader 类或 FileWriter 类即可避免这种现象。
FileReader 类和 FileWriter 类对应了 FileInputStream 类和 FileOutputStream 类。FileReader 类顺序地读取文件,只要不关闭流,每次调用 read0方法就顺序地读取源中其余的内容,直到源的末尾或流被关闭。

package io.file;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FlieRead {

	public static void main(String[] args) throws IOException {
		File file=new File("C:\\T\\word.txt");//创建文件对象
		//输出字符流

		FileWriter writer=new FileWriter(file);//创建字符输出流
		writer.write("我有一头小毛驴,我从来也不骑");//将字符串写入文件中
		writer.close();//关闭文件字符输出流
		
		//输入字符流
		FileReader reader=new FileReader(file);//创建字符输入流
		char[] ch1=new char[1024];//缓存字符数组
		int len=reader.read(ch1);//将文件中的字符读入缓存数组中
		System.out.println(new String(ch1,0,len));//将字符转为字符串输出
		reader.close();//关闭文件字符输出流
	}

}

 运行结果:

带缓存的输入/输入流

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

 BufferedlnputStream 与 BufferedOutputStream 类

BufferedInputStream 类可以对所有 InputStream 类进行带缓存区的包装以达到性能的优化。BuferedInputStrcam 类有两个构造方法;

  • BufferedInputStream(InputStream in)。
  • BufferedInputStream(InputStream in,int size)。

BufferedReader 与 BufferedWriter 类 

BufferedReader 类与 BufferedWriter 类分别继承 Reader 与 Writer 类。这两个类同时具有内部缓存机制,并能够以行单位进行输入/输出。 BufferedReader 类常用的方法如下:

  • read()方法:读取单个字符
  • readLine()方法:读取一个文本行,并将其返回为字符串。若无数据可读,返回null。

BufferedWriter 类中的方法都返回void。常用的方法如下:

  • write(String s,int off,int len)方法:写入字符串的某一部分
  • flush()方法:刷新该流的缓存
  • newLine()方法:写入一个行分隔符

在使用 BufferedWriter 类的 Write()方法时,数据并没有立刻被写入输出流,而是首先进入缓存区中如果想立刻将缓存区中的数据写入输出流,一定要调用 flush()方法。

案例代码

package io.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FlieRead {

	public static void main(String[] args) throws IOException {
		String content[]= {"好久不见","最近还好","常联系"};//写入的内容
		File file=new File("C:\\T\\word.txt");//创建文件对象
		try {
		FileWriter fw=new FileWriter(file);//文件字符输出流
		BufferedWriter bw=new BufferedWriter(fw);//换成输出流
		for(int k=0;k<content.length;k++) {//遍历要写入的内容
			bw.write(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();
		}
	}
}

运行结果:

 

 数据输入/输出流

 数据输入/输出流 (DataInputStream 类与 DataOutputStream 类)允许应用程序以与机器无关的方式从底层输入流中读取基本 Java 数据类型。也就是说,当读取一个数据时,不必关心这个数值应当是哪个字节。

DataInputStream 类提供了将字符串、double 数据、int 数据、Boolean 数据写入文件的方法;DataOutputStream 类只提供了一个readUTF()方法返回字符串。 DataInputStream 类与 DataOutputStream 类的构造方法:

  • DataInputStream 类提供了将字符串、double 数据、int 数据、Boolean 数据写入文件的方法;

  • DataOutputStream(DataOutputStream out):创建一个新的数据输出流,将数据写入一个指定基础输出流。
package io.file;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class DataOut {
	public static void main(String[] args) throws IOException {
		File file=new File("C:\\T\\word.txt");
		//创建 FileOutputStream 对象,指定要向其中写入数据的文件
		FileOutputStream fos=new FileOutputStream(file);
		//创建 DataOutputStream 对象,用来向文件中写入数据
		DataOutputStream dos=new DataOutputStream(fos);
		dos.writeBoolean(false);//将boolean数据写入文件
		dos.writeUTF("今天星期四");//将字符串写入文件
		dos.writeDouble(13.26);	//将double数据写入文件
		dos.writeInt(9);//将int数据写入文件
		dos.close();
		fos.close();
		//创建 FileInputStream 对象,指定要从中读取数据文件		
		FileInputStream fis=new FileInputStream(file);
		//创建 DataInputStream 对象,用来从文件中读取
		DataInputStream dis=new DataInputStream(fis);
		System.out.println(dis.readBoolean());//读取boolean数据
		System.out.println(dis.readUTF());//读取字符串
		System.out.println(dis.readDouble());//读取double数据 
		System.out.println(dis.readInt());//读取int数据
		dis.close();
		fis.close();
	}
}

运行结果 :

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值