------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
IO流(图)
字符流:
Reader与Writer(字符读取与字符写入流) 子类FileReader与FileWriter(专门操作文本的流)FileWriter对象一创建就必须明确被操作的文件,而且该文件会被创建到指定目录下,如果目录中有同名文件,将被覆盖。 FileWriter("文件路径",true):创建FileWriter对象时,如果在参数内添加true 代表在已有文件后进行续写。 flush();close();
FileReader文本字符读取流, 方法read(); 一次读取一个字符,并且会自动往下读。 当读到-1,代表结束。
<span style="font-size:18px;"><span style="font-size:18px;">//将c盘的一个文本文件复制到D盘字符流缓冲区:提高读取与写入效率 BufferedWriter: 方法flush():当写入数据时,必须进行刷新才能将文件写入。 方法newLine();换行符。
import java.io.*;
class CopyText
{
public static void main(String[]args)throws IOException
{
FileReader fr = new FileReader("c:\\DateDemo.java");//创建一个读取流对象并指定读取内容路径
FileWriter fw = new FileWriter("d:\\dateDemo1.java");//创建一个写入流对象,并指定写入的地址路径
char[] ch = new char[1024];//创建char类型数组,并定义大小
int num = 0;//定义一个标记
while((num=fr.read(ch))!=-1)//读取文件,并将读取到的位置用num记录
{
fw.write(new String(ch,0,num));//写出所读到的数据,并将数组转换成String类型,
//件较多时需要刷新
}
fr.close();//关闭读取流
fw.close();//关闭写入流,关闭时会刷新一次
}
}</span></span>
BufferedReader: 方法reaLine(),一次读取一行,用while循环进行不断读取,当返回空时表示读到文件末尾。
<span style="font-size:18px;"><span style="font-size:18px;">/*
通过缓冲区复制一个.java文件
*/
import java.io.*;
class CopyTextBuf
{
public static void main(String[]args)throws IOException
{
BufferedReader br = new BufferedReader(new FileReader("DateDemo.java"));//创建一个读取缓冲区流 并往里面传入一个读取流对象 并关联一个文件
BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\DateDemo1.java"));//创建一个写入缓冲区流 并往里面传入一个写入流对象 并指定一个写出路径
String line = null;//定义一个读取流标记line 初始化值为空.中转站,连同读取与写出的介质;
while((line=br.readLine())!=null)//读取文件 调用读取缓冲流的readLine方法
{
bw.write(line);//写出数据,调用写出缓冲流的write方法
bw.flush();//刷新
bw.newLine();//换行
}
br.close();//关闭读取缓冲流流
bw.close();//关闭写入缓冲流流
}
}</span></span>
装饰设计模式:
/*
装饰设计模式
当想要对已有的对象进行功能增强时
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能
那么资第一的该类称为装饰类
装饰类通常会通过构造方法接受被装饰的对象,
并基于被装饰对象的功能,提供更强的功能
<span style="font-size:18px;"><span style="font-size:18px;">*/
class Person//被装饰类
{
public void chifan()
{
System.out.println("吃饭");
}
}
class SuperPerson//装饰类
{
private Person p ;
SuperPerson(Person p)
{
this.p=p;
}
public void superChifan()
{
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
class PersonDemo
{
public static void main(String[]args)
{
Person p = new Person();
SuperPerson sp = new SuperPerson(p);
sp.superChifan();
}
}</span></span>
LineNumberReader类:(装饰类) 相当于BufferedReader。特有方法: setLineNuber(100):设置行号 getLineNumber():获取行号
字节流: InputStream:字节读取流(子类FileInputStream) OutputStream:字节读取流(子类OutputStream)
write()方法不需要刷新。
字节流缓冲区:BufferedInputStream, BufferedOutputStream
<<span style="font-size:18px;">span style="font-size:18px;">class CopyMp31
{
public static void main(String[]args)
{
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try
{long start = System.currentTimeMillis();//插入一个开始时间标记
bis = new BufferedInputStream(new FileInputStream("1.mp3"));
bos = new BufferedOutputStream(new FileOutputStream("复制11.mp3"));
int len = 0;//定义标记,可以关联读取写入流
while((len=bis.read())!=-1)//只有字符缓冲流的读取返回值类型到结束是null 其他的是-1
{
bos.write(len);//
}
long end = System.currentTimeMillis();//插入一个结束时间标记
System.out.println((end-start)+"毫秒");//打印所耗费的时间
}
catch(IOException e)
{
throw new RuntimeException("复制失败");
}
finally
{
try
{
if(bis!=null)
bis.close();
}
catch(IOException e)
{
throw new RuntimeException("读取流关闭失败");
}
try
{
if(bos!=null)
bos.close();
}
catch(IOException e)
{
throw new RuntimeException("写入流关闭失败");
}
}
}
}</span></span>
转换流:InputStreamReader OutputStreamWriter 将字节流传入 , 转换成一个字符流。
<span style="font-size:18px;"><span style="font-size:18px;">import java.io.*;
class InputStreamReaderDemo//字节流转字符流练习
{
public static void main(String[]args)throws IOException
{
//InputStream in = System.in;//定义一个键盘录入,用字节流创建
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//创建一个字节流转字符流
//键盘录入最常见写法//对象InputStreamReader接受被指定键盘录入的字节输入流对象
//然后这个整体就可以看做一个reader类的对象,用缓冲读取流BufferedReader
//接受这个对象
//OutputStream out = ;//定义一个写入流指向控制台
//OutputStreamWriter osw = ;//创建一个字节流写入转换字符流流写入对象并接收输出到控制台
//并使用缓冲字符流写入对象接收
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;//定义一个String变量line 并初始化为空
while((line=br.readLine())!=null)//用line记录 读取缓冲流用readLine方法读取到的键盘录入的数据
{
if(line.equals("over"))//定义一个标记,如果line记录到的数据是over(键盘录入Over)则输入结束
break;
bw.write(line.toUpperCase()+"\r\n");//输出到控制台键盘录入数据的大写形式
bw.flush();//刷新
//bw.newLine();//写入转换流的方法newLine 跨平台换行
}
br.close();//关闭读取缓冲流,在其内部将关闭读取流
bw.close();
}
}</span></span>
IO流操作规律 1,明确源和目的: 源:输入流,InputStream Reader 目的: 输出流: OutputStream Writer
2,操作的数据是否是纯文本 是:字符流: 不是:字节流:
3,通过设备来进行区分: 原设备:内存,硬盘,键盘。 目的设备:内存,硬盘,控制台。
1)将一个文本文件数据存储到一个文件中。 FileReader FileWriter
2)将键盘录入的数据保存到一个文件 Reader(InputStreamReader) FileWriter。
指定编码表存储数据 OutputStreamWriter(OutputStream o ,UTF-8) InputStreamReader(InputStream i ,UTF-8)
System类 方法setIn(),改变键盘录入。 方法setOut(),改变控制台输出地址。
异常的日志信息:
<pre name="code" class="java"><span style="font-size:18px;">//log4j 日志信息建立
import java.io.*;
import java.util.*;
import java.text.*;
class ExceptionInfo
{
public static void main(String[]args)throws Exception
{
try
{
int[] arr= new int[2];
System.out.println(arr[3]);
}
catch(Exception e)
{
try
{
Date d = new Date();//创建一个时间对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
<span style="white-space:pre"></span>//定义一个时间格式
PrintStream ps = new PrintStream("11122.txt");
<span style="white-space:pre"></span>//创建一个System.out类的对象ps 并指定输出地址
String s = sdf.format(d);
<span style="white-space:pre"></span>//通过format让时间d 接受一个sdf自定义时间格式
ps.println(s);//将时间打印打PS定义的文件中
System.setOut(ps);//设置System。out标准输出指向ps
<span style="white-space:pre"></span>//System.setOut(new PrintStream(""));
<span style="white-space:pre"></span>//e.printStackTrace(new PrintStream("11122.txt"));
}
catch(IOException ex)
{
throw new RuntimeException("日志文件创建失败");
}
e.printStackTrace(System.out);
}
}
}</span>
File类:用来将文件或文件夹封装成对象。可以作为参数传递给流的构造函数。 separator:与系统有关的目录分隔符。"c:"+separator+"abc"+... c盘下的abc文件下的。。。 跨平台分隔符。 方法: 1:创建 boolean createNewFile();在指定位置创建文件,如果该文件已经存在,则不创建,返回false。 creareTempFile(); 在指定目录下穿件一个新的空文件夹,使用给定的前缀和后缀名。 mkdir(); 创建文件夹; mkdirs(); 创建多级文件夹; 2:删除 boolean delete(); void deleteOnExit(); 在文件创建后写上,则在文件退出时将文件删除。 3:判断 boolean canExecute(); 是否可以执行。 compareTo(); boolean exists();文件是否存在。 isDirectory();是否是目录。 isFile();是否是文件。 isHidden();是否隐藏。 isAbsolute();是否是绝对路径,(带有盘符)。即使文件不存在也能判断。 4:获取信息 getName(); getPath(); getParent(); 文件创建时封装的绝对路径,如果没有,返回null。 getAbsolutePath(); long lastModified();最后一次修改时间 long length();文件大小。 FIle[] listRoots();列出有效的盘符。 String list(); 路径下所有文件和文件夹名称。 list(FileNameFileter ff):
<pre name="code" class="java"><span style="font-size:18px;">/*
listFiles():返回File[]
*/
import java.io.*;
class FileDemo2
{
public static void main(String[]args)
{
//File dir = new File("c:\\");
//File[] files = dir.listFiles();
//返回文件名称 listFiles() 可以对返回的文件进行File方法操作
//for(File f: files)
//{
//System.out.println(f.getName()+"++++"+f.length());
//}
listDemo_1();
}
public static void listDemo()
{
File f = new File("c:\\");
String[] names = f.list();
//列出当前目录下所有文件 包括隐藏的文件 并把文件疯转诚意个String类型的数组
for(String s : names)
//调用list方法的file对象必须是封装了一个目录,该目录还必须存在。否则异常
{
System.out.println(s);
}
}
//public static void listDemo()
{
}
public static void listDemo_1()
{
File dir = new File("d:\\java1.1\\date24");//创建一个文件,文件夹指向一个路径
File[] arr = dir.listFiles(new FilenameFilter()
//用String类型的数组存储file中list的方法列出来的文件
//在list方法中传入一个匿名内部类,FilenameFilter接口,并覆盖其方法accept
//返回.exe文件
{
public boolean accept(File dir,String name)
//覆盖接口FilenameFilter中的方法 并传入要遍历的文件,和需要去除的文件名
{
//System.out.println(dir+"......"+name);
/*
if(name.endsWith(".txt"))
{
return ture;
}
*/
return name.endsWith(".java");//取出相对的文件名条件
}
});
System.out.println(arr.length);//打印数组的长度
for(File name : arr)//遍历数组,打印出用上述方法得到的文件名
{
System.out.println(name);
}
}
public static void listRootsDemo()
{
File[] files = File.listRoots();//列出机器有效的盘符,并用File数组进行封装
for(File f : files)//罗列数组里的文件
{
System.out.println(f);
}
}
}</span>
递归:自己调用自己的方法
<span style="font-size:18px;">class FileDemo3
{
public static void main(String[]args)
{
File dir = new File("d:\\java1.1");//创建一个文件对象 并指定一个目录
showDir(dir,0);//
//int n =getSum(100);
//System.out.println(n);
}
public static int getSum(int n )//递归:自己调用自身方法,然后逐层返回
{
if(n==1)
return 1;
return n +getSum(n-1);//递归
}
public static void toBin(int num)//递归方法 十进制到二进制转换
{
while(num>0)
{
toBin(num/2);
System.out.println(num%2);
//num = num/2;
}
}
public static String getLevel(int level)//定义一个返回值为String类型的方法 并往里传入一个int类型的数据
//用于记录文件的层级
{
StringBuilder sb = new StringBuilder();//创建一个可变长度的StringBuilder集合
for(int x=0; x<level; x++)//循环 当x<level
{
sb.append(" ");
}
return sb.toString();//sb的初始化值为空,所有第一次返回一个空参数
}
public static void showDir(File dir,int level)
{
//System.out.println(dir+"目录**************************************");
System.out.println(getLevel(level)+dir.getName());//第一次打印java1.1
//第二次打印名字时level为1 目录前加双空格
level++;//level自增
File[] files = dir.listFiles();//在这里已经将一级目录中所有的参数列出
System.out.println()
for(int x=0; x<files.length;x++)
{
if(files[x].isFile())
System.out.println(getLevel(level)+files[x].getName());//第三次打印文件时level是2 前面打印4个空格
else
showDir(files[x],level);//递归,第二次调用showDir方法时返回的level是1
}
}
}</span>
删除一个带内容的目录:
<span style="font-size:18px;">/*
删除一个带文件的文件夹
删除原理
在windows中 删除目录从里完外删
递归
*/
import java.io.*;
class RemoveDir
{
public static void main(String[]args)
{
File dir = new File("c:\\haha");
removeDir(dir);
}
public static void removeDir(File dir)
{
File[] files =dir.listFiles();//隐藏的也会遍历到
for(File name : files)//遍历的时候应该排除隐藏的文件
{
if(name.isFile())
name.delete();//删除的时候会找不到隐藏的文件
else
removeDir(name);
}
dir.delete();
}
}</span>
创建一个免费试用程序代码
<span style="font-size:18px;">import java.io.*;
import java.util.*;
class RunCount
{
public static void main(String[]args)throws IOException
{
Properties prop = new Properties();//创建集合
File file = new File("count.ini");//创建文件并封装成对象
if(!file.exists())//判断文件是否存在
file.createNewFile();//不存在的话创建
FileInputStream fis = new FileInputStream(file);//创建读取流并关联file
prop.load(fis);//将流中的数据存储到prop中
int count = 0;//定义标记
String value = prop.getProperty("time");//获取键对应的值,
if(value!=null)//当键不存在的时候
{
count = Integer.parseInt(value);//用count记录使用次数.
if(count>=5)//判断count
{
System.out.println("免费次数已到,请充值");//提示并退出程序
return;
}
}
count++;//count自增
prop.setProperty("time",count+"");//将键对值从新存入集合
FileOutputStream fos = new FileOutputStream(file);//并通过写出流关联文件
prop.store(fos,"");//将集合中的内容通过流以键值对的形式写到具体文件中.
fos.close();
fis.close();
}
}</span>
打印流:PrintStream(字节打印流)与PrintWriter(字符打印流) PrintStream:构造函数可以接收的参数类型:file对象,字符串路径,字节输出流。
PrintWriter:构造函数可以接收的参数类型:file对象,字符串路径,字节输出流,字符输出流。
序列流:SequenceInputStream 构造函数接收多个流进入,从第一个流开始读取,到最后一个流结束,去读取数据。
<span style="font-size:18px;">/*
SequenceInputStream:将多个个流连接
*/
import java.io.*;
import java.util.*;
import java.io.SequenceInputStream;
class SequenceInputStream1
{
public static void main(String[]args)throws IOException
{
Vector<FileInputStream> v = new Vector<FileInputStream>();//创建一个Vector集合
v.add(new FileInputStream("c:\\1.txt"));//添加流对象元素并关联文件
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));
System.out.println(v.size());//打印集合长度
//Enumeration<FileInputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(v.elements());//创建多个流连接对象
//并传入由v封装的多个流,用Vector的方法elements得到Enumeration枚举的对象
FileOutputStream fos = new FileOutputStream("c:\\4.txt");//创建一个写入流,并关联一个输出文件
byte[] arr = new byte[1024];//创建一个数组存储数据
int num = 0;//定义一个标记
while((num=sis.read(arr))!=-1)
{
fos.write(arr,0,num);//写出数据
}
fos.close();
sis.close();
}
}</span>
split流的切割
<span style="font-size:18px;">/*
split切割文件
*/
import java.io.*;
import java.util.*;
import java.io.SequenceInputStream;
class SplitDemo
{
public static void main(String[]args)throws IOException
{
merge();
}
public static void splitFile()throws IOException
{
FileInputStream fi = new FileInputStream("11.mp3");//创建一个读取流 关联一个文件
FileOutputStream fos = null;//创建一个写入流引用
byte[] arr = new byte[1024*1024];//创建一个存储数组
int count = 1;//标记一个
int len = 0;//标记
while((len=fi.read(arr))!=-1)//读取
{
fos = new FileOutputStream((count++)+".part");//创建写出流
fos.write(arr,0,len);//写出去
fos.close();//关闭流
}
fi.close();
}
public static void merge()throws IOException
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();//创建一个存储读取流的集合
for(int x = 1; x<=4; x++)
{
al.add(new FileInputStream(x+".part"));
}
final Iterator<FileInputStream> it = al.iterator();//迭代取出al中的片段
Enumeration <FileInputStream> en = new Enumeration<FileInputStream>()//匿名内部类访问的局部成员要用final修饰
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()
{
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);//创建一个大流接受片段流
FileOutputStream fos = new FileOutputStream("0.mp3");//创建输出流
byte[] buf = new byte[1024];
int num = 0;
while((num=sis.read(buf))!=-1)
{
fos.write(buf,0,num);//写出数剧
}
fos.close();
sis.close();
}
}</span>
ObjectInputStream与ObjectInputStream(直接操作对象的流)
被操作的对象需要实现Serializable(标记接口)。
ObjectInputStream可以操作基本数据类型
每一个类在序列化的时候都会存在一个UID,根据类的内容计算出来的。当被序列化就是对象的持久化,将对象存储到硬盘上。 当一个类的内容被改变时,这个类的UID也会被改变,这样就不能再用ObjectInputStream读取到该类中的数据。可以用public static final long serialVersionUID = 42L;来设置一个固定的UID。
transient关键字, 用这个关键字修饰的变量不能被序列化。
<span style="font-size:18px;">public class ObjectStreamDemo {
public static void main(String[] args)throws IOException, ClassNotFoundException {
readobj();
}
public static void readobj() throws FileNotFoundException, IOException, ClassNotFoundException
{
ObjectInputStream ois =
new ObjectInputStream(new FileInputStream("obj.txt"));//将文件读取并打印在控制台上。
Person p = (Person)ois.readObject();//一次读取一个对象
System.out.println(p);
ois.close();
}
public static void writeObj() throws IOException {//将对象持久化存储到文件中
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi",30));
oos.close();
}
}</span>
RandomAccessFile类,直接继承与Object 随机访问文件,自身具备读写的方法。通过skipBytes(int x),seek(int x)来达到随机访问 它内部封装了一个byte数组,通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置。(内部封装了字节流)。。。。。。局限性:该类只能操作文件。 并且有mode模式:r 读,rw,读写。如果是r则不能写数据。 如果模式为只读,不会创建文件,回去读取一个已存在的文件,如果该文件不存在,则会出现异常。如果模式为rw,需要操作的文件不存在,则创建,存在则不会覆盖。
<span style="font-size:18px;">import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
//readFile();
writeFile2();
}
public static void readFile() throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
//调整对象中的指针
//raf.seek(8*1);//设置角标位置。
raf.skipBytes(8);//跳过8个字节,不能往回跳
byte[]buf = new byte[4];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println(name);
System.out.println(age);
raf.close();
}
public static void writeFile() throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");//创建读写的RandomAccessFile对象。
raf.write("李四".getBytes());
raf.writeInt(88);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
public static void writeFile2() throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
raf.seek(8*3);//指定位置读写,如果设置的角标有数据,则覆盖。,实现数据的分段存入。
raf.write("周七".getBytes());
raf.writeInt(88);
raf.close();
}
}</span>
管道流:PipedInputStream和PipedOutputStream,输入输出可以直接进行谅解,通过结合线程使用。(设计到多线程) 构造函数相互作为参数传入。
<span style="font-size:18px;">import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipedStreamDemo {
public static void main(String[] args) throws IOException {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);
Read r = new Read(in);
Write w = new Write(out);
new Thread(r).start();//1
new Thread(w).start();//2
}
}
class Read implements Runnable
{
private PipedInputStream in;
Read(PipedInputStream in)
{
this.in=in;
}
public void run()
{
try
{
byte[] buf = new byte[1024];
int len = in.read(buf);//没有数据等待,下面写数据到这里来
String s = new String(buf,0,len);//
System.out.println(s);//写出数据
in.close ();
}
catch(IOException e)
{
throw new RuntimeException("管道流读取失败");
}
}
}
class Write implements Runnable
{
private PipedOutputStream out;
Write(PipedOutputStream out)
{
this.out = out;
}
public void run()
{
try
{
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.write("管道来了".getBytes());//写出数据 ,写到上面的读取流中
out.close ();
}
catch(IOException e)
{
throw new RuntimeException("管道流输出失败");
}
}
}</span>
DataInputStream与DateOuputStream(操作基本数据类型)
<span style="font-size:18px;">import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class DateStreamDemo {
public static void main(String[] args) throws IOException {
writeDate();
read();
writeUTFDemo();
readUTFDemo();
}
public static void readUTFDemo() throws IOException//读UTF
{
DataInputStream dis = new DataInputStream(new FileInputStream("UTFDATE.txt"));
String s = dis.readUTF();
System.out.println(s);
dis.close();
}
public static void writeUTFDemo() throws IOException//写UTF编码
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("UTFDATE.txt"));
dos.writeUTF("你好");
dos.close();
}
public static void writeDate() throws IOException {//写基本数据
DataOutputStream dos = new DataOutputStream(new FileOutputStream("date.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(3.14);
}
public static void read() throws IOException//读基本数据
{
DataInputStream dis = new DataInputStream(new FileInputStream("date.txt"));
int num = dis.readInt();
boolean b = dis.readBoolean();
double d = dis.readDouble();
System.out.println(num);
System.out.println(b);
System.out.println(d);
}
}</span>
ByteArrayInputStream与ByteArrayInputStream(操作字节数组)内部都有缓冲。 ByteArrayInputStream:没有调用过底层资源,不会产生IO异常。 ByteArrayInputStream:没有调用过底层资源,不会产生IO异常。
CharArrayReader与CharArrayWrite(操作字符数组)
StringReader与StringWriter(操作字符串)
IO异常的处理方式:
<span style="font-weight: normal;">class FileWriterDemo2
{
public static void main(String[]args)
{
FileWriter fw =null;//建立外部引用
try{
fw = new FileWriter("文件路径");
fw.Writer("数据");
}
catch(IOException e)
{
System.out.println(e.toString());
}
finally
{
try{
if(fw!=null)//如果不判断,当fw不存在,就会发生关闭失败异常。
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}</span>
<span style="font-weight: normal;">class FileWriterDemo2
{
public static void main(String[]args)
{
FileWriter fw =null;//建立外部引用
try{
fw = new FileWriter("文件路径");
fw.Writer("数据");
}
catch(IOException e)
{
System.out.println(e.toString());
}
finally
{
try{
if(fw!=null)//如果不判断,当fw不存在,就会发生关闭失败异常。
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}</span>