System.out.println(fileName[i]);
}
}
}
publicclassFileAcceptimplementsFilenameFilter{
Stringstr=null;
publicFileAccept(Strings){
//TODO自动生成构造函数存根
str="."+s;
}
publicbooleanaccept(Filedir,Stringname){
//TODO自动生成方法存根
returnname.endsWith(str);
}
}
文件的创建与删除:
(如下例)
Filef=newFile("c:
\\","letter.dat"); //先用File类创建一个文件对象。
if(!
f.exists()){ //如果该文件夹中没有该文件,就新建一个
try{
f.createNewFile();
}
catch(IOExceptione){
}
}
if(f.exists()){ //如果存在该文件,就删除。
也可以之间用f.deleteOnExit()方法。
f.delete();
}
运行可执行文件:
要运行一个可执行文件,用java.lang.Runtime类。
先用Runtime类声明一个对象,如:
Runtimerun;
然后用该类的类方法getRuntime()创建这个对象,如:
run=Runtime.getRuntime();
其中run可以调用exec(Stringcommand)方法打开本地机子上的可执行文件或执行一个操作。
示例如下:
try{
Runtimerun=Runtime.getRuntime();
Filefile=newFile("c:
\\windows","Notepad.exe");
run.exec(file.getAbsolutePath());
}
catch(Exceptione){
System.out.println(e);
}
字节输入输出流类:
(FileInputStream类和FileOutputStream类)
当文件读取需求比较简单时,可使用FileInputStream类,该类派生于InputStream类。
FileInputStream类常用构造方法两个:
FileInputStream(Stringname) //使用给定文件名name创建FileInputStream对象
FileInputStream(Filefile) //使用File对象创建FileInputStream对象
使用FileInputStream文件输入流对象读取文件,示例如下:
FileInputStreamistream=newFileInputStream("hello.txt");
或
Filefile=newFile("hello.txt");
FileInputStreamistream=newFileInputStream(file);
处理I/O异常:
使用文件输入流构造方法创建对象可能会出现错误,如要打开的文件不存在等,使用IOException对象表示这个出错信号。
程序必须捕获处理这个异常。
类似如下:
try{
FileInputStreamistream=newFileInputStream("hello.txt");
}
catch(IOExceptione){
System.out.println("Filereaderror:
"+e);
}
(I/O操作对于错误特别敏感,所有许多流类的构造方法和读写方法都会引起I/O异常,程序必须捕获处理这些异常。
)
从输入流读取字节:
输入流调用read()方法从输入流中读出数据。
方法如下:
intread(); //顺序读取源中单个字节数据,返回字节值(0-255整数),如果到达源末尾,返回-1。
intread(byteb[]); //读取b.length个字节,存放在数组b中,返回实际读取的字节数。
intread(byteb[],intoff,intlen) //读取len个字节,存放在数组b中,off是首字节在数组中的存放位置,返回实际读取字节数。
(read()方法顺序读取文件,只要流不关闭,每次调用read()方法就顺序读取源中其余内容,直到源的末尾或流关闭!
)
关闭流:
使用完流关闭它是个好习惯,尽管java在程序结束时会自动关闭所有打开的流。
因为一个被打开的流可能会用尽系统资源,这取决与平台和实现。
如果不关闭被打开的流,就可能不允许另一个程序操作利用这些流所用的资源。
关闭输出流的另一个原因是保证操作系统把流缓冲区的数据写到磁盘上(目的地)。
可以用文件输入/输出流对象调用close()方法关闭流。
FileOutputStream类与FileInputStream类对应。
构造方法及其使用与FileOInputStream一致。
可以用输出流对象调用write方法把字节写入到输出流,到达目的地。
如下:
publicvoidwrite(intb) //将指定字节写到输出流
publicvoidwrite(byteb[]) //写b.length个字节到输出流
publicvoidwrite(byteb[],intoff,intlen) //从字节数组b中起始于偏移量off处写入len个字节到输出流
(FileOutputStream流顺序地写文件,只要不关闭流,每次调用write()方法就顺序地向输出流写入数据,直到流关闭!
)
字符输入输出流类:
(FileReader类和FileWriter类)
字节输入输出流类以字节单位读写数据,不能很好的操作Unicode字符。
如果使用字符流就不容易出现乱码问题。
FileReader和FileWriter分别是Reader和Writer的子类,构造方法如下:
FileReader(Stringname); FileReader(Filefile);
FileWriter(Stringname); FileWriter(Filefile);
字符输入/输出流的read()和Write()方法使用字符数组读写数据,以字符(char)为基本单位。
常用方法如下:
intread() //从源中读取一个字符,返回一个Unicode字符值(0-65535整数),未读出字符返回-1。
intread(charb[])
intread(charb[],intoff,intlen)
voidwrite(intn) //向目的地写入一个字符(Unicode字符值)
voidwrite(charb[])
voidwrite(charb[],intoff,intlen)
BufferedReader类和BufferedWriter类:
当需要每次读写一行,无法知道一行有多少字符,即字符数组大小无法确定,这时FileReader,FileWriter类就很难完成这样的任务。
java中用BufferedReader和BufferedWriter流可以完成这样的工作。
二者的源和目的地必须是字符输入流和字符输出流。
因此,可以把Reader(字符输入流)作为BufferedReader流的源,把Writer(字符输出流)流作为BufferedWriter流的目的地。
构造方法如下:
BufferedReader(Readerin);
BufferedWriter(Writerout);
用BufferedReader类对象调用readLine()方法读取文本行:
FileReaderfilereader=newFileReader("Student.txt");
BufferedReaderin=newBufferedReader(filereader);
StringstrLine=in.readLine();
类似的,可以将BufferedWriter流和FileWriter流连接在一起,然后使用BufferedWriter流将数据写到目的地,如:
FileWriterfilewriter=newFileWriter("Student.txt");
BufferedWriterout=newBufferedWriter(filewriter);
然后输出使用BufferedWriter类的方法,如:
write(Strings,intoff,intlen) //把字符串s写到Student.txt中,off是s开始处的偏移量,len是写入的字符数量。
可以把BufferedReader和BufferedWriter称作上层流,把它们指向的字符流称作底层流。
java采用缓存技术将上层流和底层流连接。
底层字符输入流先把数据读入缓存,BufferedReader流再从缓存读取数据;BufferedWriter流将数据写入缓存,底层字符输出流会不断地将缓存中的数据写到目的地。
当BufferedWriter流调用flush()方法刷新缓存或调用close()方法关闭时,即使缓存还没有溢满,底层流也会立刻将缓存的数据写到目的地。
RandomAccessFile类:
Java提供了更完善的用来处理文件输入输出操作功能的RandomAccessFile流,该流的指向既可以作为源也可以作为目的地,也就是说对一个文件进行读写操作时,创建一个指向文件的RandomAccessFile流即可。
RandomAccessFile类两个构造方法:
RandomAccessFile(Stringname,Stringmode) //mode取r(只读)或rw(可读写)
RandomAccessFile(Filefile,Stringmode) //mode取r(只读)或rw(可读写)
RandomAccessFile类中有个方法seek(longa),用来定位RandomAccessFile流的读写位置,参数a确定读写位置距离文件开头的字节数。
还可以调用getFilePointer()方法获取流当前读写位置。
RandomAccessFile流对文件的读写比顺序读写更为灵活!
(该类还有许多方法,详细查看JDK)
数据流:
(DataInputStream和DataOutputStream类)
数据输入流和数据输出流,允许程序按照与机器无关的风格读取Java原始数据。
也就是说,当读取一个数值时,不必关心这个数值应该是多少字节。
构造方法:
DataInputStream(InputStreamin) //将创建的数据输入流指向一个由in指定的底层输入流
DataInputStream(OutputStreamout) //将创建的数据输出流指向一个由out指定的底层输出流
(这个流类很神奇!
Java确实提供了很多C++程序员很渴望的高级工具,详细查看JDK吧)
带进度条的输入流:
使用javax.swing.ProgressMonitorInputStream类创建的输入流读取文件时可以看见文件的读取进度。
构造方法如下:
ProgressMonitorInputStream(Componentc,Objectmessage,InputStreamin) //进度条在c指定组件正前方显示,若取null,则在屏幕正前方显示,message指定在进度条上的显示信息(String)
示例如下:
importjavax.swing.*;
importjava.io.*;
importjava.awt.*;
importjava.awt.event.*;
publicclasstest1{
publicstaticvoidmain(String[]args){
byteb[]=newbyte[2];
JTextAreatext=newJTextArea(20,20);
JFramejframe=newJFrame();
jframe.setSize(280,300);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.add(newJScrollPane(text),BorderLayout.CENTER);
jframe.validate();
try{
FileInputStreaminput=newFileInputStream("test1.java");
ProgressMonitorInputStreaminput_progress=newProgressMonitorInputStream(jframe,"读取java文件",input);
ProgressMonitorp=input_progress.getProgressMonitor();
while(input_progress.read(b)!
=1){
Strings=newString(b);
text.append(s);
Thread.sleep(10);
}
}
catch(Exceptione){}
}
}
对象流:
(ObjectInputStream和ObjectOutputSteam类)
ObjectInputStream(对象输入流)和ObjectOutputSteam(对象输出流)类分别是InputStream和OutputStream类的子类。
ObjectInputStream对象调用readObject()方法读取一个对象到程序中,ObjectOutputStream对象调用writerObject(Objectobj)方法将一个对象obj写入到一个文件。
两个类构造方法如下:
ObjectInputStream(InputStreamin) //in为InputStream的子类创建的输入流对象
ObjectOutputSteam(OutputStreamout) //out为OutputStream的子类创建的输出流对象
使用对象流时,要保证对象是序列化的。
这是为了保证能把对象写入文件并能正确读回到程序的缘故。
一个类实现了Serializable接口,它创建的对象就是序列化的。
(Serializable接口中的方法对程序不可见,由JVM自动实现,因此实现该接口不需要实现额外的方法。
但要注意,使用对象流把一个对象写入到文件时,除了要保证对象是序列化的,还要保证对象的成员对象也必须是序列化的。
)
示例:
importjava.io.*;
publicclassStudentimplementsSerializable{
Stringname=null;
doubleheight;
publicStudent(Stringname,doubleheight){
//TODO自动生成构造函数存根
this.name=name;
this.height=height;
}
publicvoidsetHeight(doublec){
this.height=c;
}
}
publicclasstest1{
publicstaticvoidmain(String[]args){
Studentzhang=newStudent("张三",1.65);
try{
FileOutputStreamfile_out=newFileOutputStream("s.txt");
ObjectOutputStreamobject_out=newObjectOutputStream(file_out);
object_out.writeObject(zhang);
FileInputStreamfile_in=newFileInputStream("s.txt");
ObjectInputStreamobject_in=newObjectInputStream(file_in);
Studentli=(Student)object_in.readObject();
li.setHeight(1.78);
li.name="李四";
System.out.println(zhang.name+"身高是:
"+zhang.height);
System.out.println(li.name+"身高是:
"+li.height);
}
catch(ClassNotFoundExceptionevent){
System.out.println("不能读出对象");
}
catch(IOExceptionevent){
System.out.println("cannotreadfile"+event);
}
}
}
序列化与对象克隆:
一个类的两个对象如果具有相同引用,那么他们具有相同的实体和功能。
如:
Aone=newA();
Atwo=one;
这样对one成员变量的操作将会改变two中的成员变量(两个实体是同一个)。
如果想得到对象的克隆对象(克隆对象