黑马程序员 总结(十七)——I/O流(一)

本文详细介绍了Java I/O流的概念、分类、基本类及其使用方法,包括字符流的写入、续写、缓冲区写入、文本读取、文件读写应用,以及如何使用装饰设计模式来动态扩展对象功能。此外,还涵盖了IO异常的处理策略,确保程序的健壮性和稳定性。

------- android培训java培训、期待与您交流! ----------

I/O流

程序在执行时通常要和外部进行交互,从外部读取数据或向外部设备发送数据,这就是所谓的I/O。Java使用抽象概念——流(stream)来描述程序与数据发送或者接收的通道。I/O流有不同的分类,按照流的方向分为输入流和输出流。按照操作的数据分为字节流和字符流。在I/O流中有四个基本抽象类,字节流2个,字符流两个。字节流的抽象基类是:InputStream和OutputStream两个。字符流的抽象基类是:Reader和Writer两个。由这四个类派生出来的子类名称都是以其父类名作为子类名的后半部分。

字符流——Writer

一、FileWriter

1、简介:用来写入字符文件的便捷类,用于写入字符流。

2、构造方法:

1、FileWriter(File file):根据给定的 File 对象构造一个 FileWriter 对象。

2、FileWriter(File file, boolean append) :根据给定的 File 对象构造一个 FileWriter 对象,当append为true为真时,则是在给定的File对象后面添加。

3、FileWriter(FileDescriptor fd) :构造与某个文件描述符相关联的 FileWriter 对象

4、FileWriter(String fileName) :根据给定的文件名构造一个 FileWriter 对象

5、FileWriter(String fileName, boolean append):根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

二、字符流的写入

1、导入java.io包。

2、创建一个FileWriter(写入字符流)对象,该对象只有自己特有的构造方法用于创建对象。在创建该对象时必须指定要操作的文件。该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。实际上该步就是在明确操作的对象。

3、调用public void write()方法,将要写入的数据写入到流中。

4、调用public void flush()方法,将流中的数据写入到文件中。

5、如果是最后一次写入数据,则可以public void close()方法,将流中的数据刷到目标文件中,并且在刷新后关闭该流。

注:在建立写入字符流对象,操作完成后必须调用close方法关闭流对象。


示例:


import java.io.*;
class MyFileWriter 
{
	public static void main(String[] args) throws IOException,InterruptedException
	{
		FileWriter fw = new FileWriter("hello.java");
			//调用write方法往hello.java文件中写入流中
		fw.write("import java.io.*;");
			//调用flush方法将流中的数据写到hello.java文件中
		fw.flush();
			//继续往流中写入数据
		fw.write("\nclass MyFileWriter");
			//将流中数据写入文件中
		fw.close();
		
			//使用Runtime类的方法,打开建立的文件,并且在5秒后自动关闭。
		Runtime rt = Runtime.getRuntime();
		Process p = rt.exec("E:\\xp\\Program Files\\EditPlus 3\\EditPlus.exe J:\\JAVA\\day18\\hello.java");
		Thread.sleep(5000);
		p.destroy();
	}
}


三、文件的续写,即在原文件的基础上继续写。

1、方法:利用FileWriter的的FileWriter(String fileName, boolean append)构造方法。此时,不会新建文件,而是当源文件存在时在原文件的基础上添加。操作方法和字符流的写入一样。

2、在记事本中\r\n代表换行。

四、BufferWriter:

1、简介:字符流写入缓冲区,将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。

2、写入流缓冲区的创建:

1.因为缓冲区的出现是为了提高流的工作效率,所以在创建缓冲区之前,必须要有流对象。所以首先得创建写入流的对象。

2.把需要提高效率的流对象作为参数传递给缓冲区的构造函数即可。

3、工作原理:可以理解为在缓冲区内封装了数组。

4、缓冲区的关闭:缓冲区的关闭实际上是关闭与该缓冲区关联的流对象。

5、缓冲区类的方法和写入流方法的对比:

缓冲区是为了提高工作效率而出现的,所以缓冲区的方法和写入流的方法基本相同。只是写入流有String getEncoding()方法,返回该写入流使用的字符编码名称。在缓冲区类中有有public void newLine()方法,写入一个换行符。因为不同的操作系统,换行符的表现形式不一样。为了实现跨平台性,让jvm调用系统的方法加上该系统的换行符。


五、IO异常的处理

1、IO异常的由来:因为IO的操作在调用资源,所以在和设备上的数据进行操作的都可能会发生异常。

2、如果几个连续的语句都可能抛IO异常,则把这几个语句放在一个try语句里,因为如果上面发生异常,下面的语句也就没必要继续运行。

3、定义异常处理的方式的时候,因为关流的操作必须得进行,所以把关流的语句放在finally语句块中。

4、在两个语句块中都要用到流对象,所以流对象在try语句块的上面建立引用,在里面建立对象。这样finally才能使用关闭流的功能。

5、finally中关闭流资源的操作也可能抛出IO异常,所以在finally语句中要对关闭流操作的语句也要进行try处理。

6、如果在初始化时抛出IO异常,则流对象没有建立成功,但是还是要执行finally语句中关闭流的语句。所以在关闭流对象的语句前面应该加一句流对象是否为null的判断。


示例


import java.io.*;
class MyFileWriter 
{
	public static void main(String[] args)
	{
		FileWriter fw = null;
		try
		{
			fw = new FileWriter("hello.java");
			//调用write方法往hello.java文件中写入流中
			fw.write("import java.io.*;");
			//调用flush方法将流中的数据写到hello.java文件中
			fw.flush();
			//继续往流中写入数据
			fw.write("\nclass MyFileWriter");
		}
		catch (IOException e)
		{
			System.out.println("deal:"+e);
			return;
		}
		//关闭流资源
		finally
		{
			if(fw!=null)
				try
				{
					fw.close();
				}
				catch (IOException e)
				{
					System.out.println("deal with:"+e);
					return;
				}
		}

		//使用Runtime类的方法,打开建立的文件,并且在5秒后自动关闭。
		
		Runtime rt = Runtime.getRuntime();
		Process p = null;
		//处理打开进程可能抛出的异常
		try
		{
			p = rt.exec("E:\\xp\\Program Files\\EditPlus 3\\EditPlus.exe J:\\JAVA\\day18\\hello.java");	
		}
		catch (IOException e)
		{
			System.out.println("deal:"+e);
			return;
		}
		//处理延时抛出的终端异常
		try
		{
			Thread.sleep(5000);
		}
		catch (InterruptedException e)
		{
			System.out.println("时间到");
		}
		p.destroy();
	}
}


字符流——Reader

一、FileReader(与FileWriter相对)

1、简介:用来读取字符文件的便捷类,用于读取字符流。

2、构造方法:

1、FileReader(File file)  :在给定从中读取数据的File 的情况下创建一个新FileReader。

2、FileReader(FileDescriptor fd):在给定从中读取数据的FileDescriptor 的情况下创建一个新FileReader

3、FileReader(String fileName) :在给定从中读取数据的文件名的情况下创建一个新FileReader

二、文本文件的读取

1、通过Reader类中int read()方法,一个字符一个字符的读取。

步骤:和写入字符的类似。

示例:

import java.io.*;
class MyFileReader
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("SystemDemo.java");

		for(int num=fr.read();num!=-1;num=fr.read())
		{
			System.out.print((char) num);
		}
		fr.close();
	}
}


2、通过Reader类中int read(char[] arr)方法,一段字符一段字符的读取。

示例:

import java.io.*;
class MyFileReader
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("SystemDemo.java");
		char[] i = new char[10];

		for(int num=fr.read();num!=-1;num=fr.read())
		{
			System.out.print(new String(i,0,num));
		}
		fr.close();
	}
}
注意:1、在打印的时候不能用ln,如果用ln就可能原文件没有换行,在打印到屏幕上的时候却换行了。

  2、结束的时候一定要关闭流。



文件读写应用的实验:

·1、需求:把当前目录下的一个文本文件,复制到另一个文件夹。

2、原理:在指定目录新建一个文本文件并与之关联输出流。把当前目录下的文本文件与输入流关联,把从该文件读取的内容写到指定目录的文件中。

3、示例:

import java.io.*;
class  ReadWrite
{
	public static void main(String[] args) throws IOException
	{	
		//建立输出流和输入流的流对象
		FileWriter fw = new FileWriter("d:\\SystemDemo.txt",true);
		FileReader fr = new FileReader("SystemDemo.java");
		//把文本文件的内容取出并写入另一个文件
		char[] a = new char[1024];
		int flag = fr.read(a);
		while (flag!=-1)
		{
			fw.write(new String(a,0,flag));
			fw.flush();
			flag = fr.read(a);
		}
		//关闭流资源
		fw.close();
		fr.close();
	}
}

注意:在输出流向目标文件写入数据的时候,必须要调用输入流的flush方法,把流中的数据刷入文件。


三、BufferReader

1、简介:和BufferWriter一样,只是BufferReader是提高读的效率的缓冲区,BufferWriter是提高写效率的缓冲区。

2、BufferReader的创建和关闭:和BufferWriter一样,只是在关闭的时候不会刷新。

3、BufferReader和FileReader的对比:

BufferReader中定义了String readLine()读取文本的一行但是该方法返回的不包含终止符。进行了高效读取,当读取完后返回的是null.

注意:readLine()方法,返回的只是回车符之前的字符串。所以在拷贝文件时要手动的添加newLine()方法。


装饰设计模式

     装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。目的是对该真实的对象进行功能的增强。

1、装饰类:定义一个类,将要扩展的对象传入,基于已有的功能,并提供加强功能。该类就被称为装饰类。

2、实现方法:装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。

3、装饰和继承的区别:

1.继承用来拓展特定对象的功能,装饰可以通过多态的特性将一类对象的功能拓展。

2.通过装饰可以避免通过继承带来的程序臃肿的问题。

3.通过继承得到的体系拓展性没有装饰得到的体系拓展性好。

4.因为装饰类是增强已有对象的功能,具备的功能和已有的功能是相同的,只不过提供了更强的功能,所以装饰类和被装饰类是属于同一个体系。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值