1、第十五章第十五章 输入输出流与文件操作输入输出流与文件操作 2 3本章知识重点3132输入输出流的分类33java.io包中流的体系结构34目录和文件管理涉及到的类输入输出流的概念 4本章知识难点33java.io包中的输入输出流类3132目录和文件管理涉及到的类流输入及输出的一般过程 5输入输出流的分类 Java 流的概念 Java使用流(stream)来执行输入输出(I/O)的功能,流是一 种数据的源头和目的之间的通信途径 标准输入输出 Java系统事先定义好两个流对象,分别与系统的标准输入 和标准输出相联系,它们是System. in和System.out System是Java中一个功
2、能很强大的类,利用它可以获得很 多Java运行时的系统信息。 3132【例15.1】 6输出流输出流(程序写出数据程序写出数据) 输入流输入流(程序读入数据程序读入数据) Java中根据流操作的种类可分为:字节流和字符流根据流的方向,流可分为两类:输入流和输出流Java流类体系结构流类体系结构1 Java流类体系结构流类体系结构2Java流类体系结构流类体系结构3 Java流类体系结构流类体系结构4 Java流的概念输入输出流的分类 7目录和文件管理目录和文件管理 32文件名的处理文件名的处理 31FileFile类类 文件或目录的生成文件或目录的生成 文件属性测试文件属性测试 普通文件信息和
3、工具普通文件信息和工具 目录操作目录操作 public File(String path):如果path是实际存在的路径,则该File对象表示的是目录;如果path是文件名,则该File对象表示的是文件。public File(String path,String name):path是路径名,name是文件名(不可为空)。public File(File dir,String name):dir是路径名,name是文件名。String getName( ):得到一个文件的名称(不包括路径)。String getPath( ):得到一个文件的路径名。String getAbsolutePath
4、( ):得到一个文件的绝对路径名。String getParent( ):得到一个文件的上一级目录名。String renameTo(File newName):将当前文件名更名为给定文件的完整路径。【例15.2】 boolean exists( ):测试当前File对象所指示的文件或目录是否存在,若存在,返回True。boolean createNewFile():创建当前文件。boolean canWrite( ):测试当前文件是否可写。boolean canRead( ):测试当前文件是否可读。boolean isFile( ):测试当前文件是否是文件(不是目录)。boolean isD
5、irectory( ):测试当前文件是否是目录,若为目录则返回True。【例15.3】 long lastModified( ):得到文件最近一次修改的时间。long length( ):得到文件的长度,以字节为单位,若不存在,返回0。boolean delete( ):删除File对象代表的文件或目录,目录需为空。删除成功,返回True。boolean mkdir():生成一个由该对象指定的路径(新目录),若成功,返回True。boolean mkdirs():生成一个新的目录,包含子目录。若成功,返回true。boolean renameTo(File newName):将当前File对象
6、所代表的路径名改为newName所代表的路径名。若成功,返回true。String list():列出当前目录下的文件。File listFiles():得到该对象所代表的目录下的File对象数组。String toString():得到抽象路径表示法。【例15.4】 FileFile类的应用类的应用 【例15.5】 【例15.6】 8字节流字节流 缓冲区流缓冲区流BufferedInputStream和BufferedOutputStream 33顺序读/写文件(FileInputStream与FileOutputStream) 31ByteArrayInputStream和ByteArra
7、yOutputStream 32 9顺序读/写文件(FileInputStream与FileOutputStream) FileInputStream类从磁盘文件读取数据。常用的构造方法有:FileInputStream(String name):打开文件name用来读取数据。如:FileInputStream f =new FileInputStream(c:/test.txt);FileInputStream(File file):打开文件file用来读取数据。如:File f=new File(c:/test.txt); FileInputStream f1=new FileinputS
8、tream(f);将FileDescriptor对象作为其参数。如:FileDescriptor() fd=new FileDescriptor(); FileinputStream f2=new FileInputstream(fd);FileOutputStream类创建文件(如果文件不存在),并将数据写入文件。FileOutputStream类常用的构造方法有:FileOutputStream(String name):打开文件name用来写入数据。如:FileOutputStream f=new FileOutputStream (c:/test.txt);FileOutputStre
9、am(File file):打开文件file用来写入数据。如:File f =new File(c:/test.txt);FileOutputStream f1=new FileOutputStream (f);FileOutputStream(String name,Boolean append):打开文件name用来写入数据,若append为true,则写入的数据会加到原有文件后面,否则,覆盖原有的文件。如:FileOutputStream f =new FileOutputStream(c:/test.txt,true);将FileDescriptor对象作为其参数。FileDescri
10、ptor() fd =new FileDescriptor();FileOutputStream f =new FileOutputStream(fd);【例例15.7】 字节流字节流 10ByteArrayInputStream和ByteArrayOutputStream 字节流字节流 ByteArrayInputStream 将字节数组用作源,并在该数组中执行读操作它有两种构造方法。第一种构造方法将字节数组作为参数。ByteArrayInputStream(byte buffer):生成一个字节数组的输入流,并指定一个字节数组buffer为此输入流的流缓冲区。如:ByteArrayInpu
11、tStream b =new ByteArrayInputStream(buf);另外一种构造方法有助于从指定的字节数组来创建ByteArrayInputStream。ByteArrayinputStream b =new ByteArrayinputStream(buf,off,len);其中off 是要读取的第一个字节的偏移,len 是要读取数组的字节数;ByteArrayOutputStream有2种构造方法ByteArrayOutputStream():生成一个字节数组的输出流,其缓冲区的默认初始大小为32字节,若有需要,缓冲区的大小会随之增加。如:ByteArrayOutPutStr
12、eam b=new ByteArrayOutputStream();ByteArrayOutputStream(int size):创建32个自己的缓冲器用于储存数据,但分配size字节的初始大小给此缓冲区。如:ByteArrayOutputStream b1=new ByteArrayOutputStream(size);创建大小为size的缓冲器ByteArrayOutputStream的一些常用方法:int size():返回此流缓冲区的大小。byte toByteArray():生成一个新的字节数组,并将流的内容复制到此字节数组。String toString():将流的内容转换为St
13、ring对象。【例15.8】 11字节流字节流 缓冲区流缓冲区流BufferedInputStream和BufferedOutputStream BufferedInputStream类的构造方法和方法:BufferedInputStream(InputStream in):构造一个BufferedInputStream。BufferedInputStream(InputStream in, int size):构造一个具有给定的缓冲区大小的BufferedInputStream。int available():得到可以从这个输入流读取的字节数。void close():关闭流。void ma
14、rk(int readlimit):在这个输入流的当前位置做标记。boolean markSupported():检查这个输入流是否支持mark和reset方法。int read():读取数据的下一个字节。int read(byte b, int off, int len):从这个字节输入流的给定偏移量处开始读取字节,存储到给定的字节数组。void reset():将缓冲区重新设置到加标记的位置。long skip(long n):跳过n个字节的数据。BufferedOutputStream类的构造方法和方法:BufferedOutputStream(OutputStream out):构造一
15、个BufferedOutputStream。BufferedOutputStream(OutputStream out, int size):构造一个具有给定的缓冲区大小的BufferedOutputStream。void flush():刷新这个流。void write(byte b, int off, int len):将给定的字节数组写到这个缓冲输出流。void write(int b):将给定的字节写到这个缓冲输出流。 【例15.9】 12字符流字符流 31ReaderReader和和Writer Writer 32InputStreamReaderInputStreamReader和
16、和OutputStreamWriterOutputStreamWriter 33FileReaderFileReader 34FileWriterFileWriter 35BufferedReaderBufferedReader和和BufferedWriterBufferedWriter 36CharArrayReaderCharArrayReader和和CharArrayWriterCharArrayWriter 13字符流字符流InputStreamReader和OutputStreamWriter InputStreamReader类的构造方法和方法:InputStreamReader(
17、InputStream in):构造一个InputStreamReader。InputStreamReader(InputStream in, String enc):使用命名的字符编码构造一个InputStreamReader。void close():关闭流。String getEncoding():得到字符编码的名称。int read():读取一个字符。int read(char cbuf, int off, int len):将字符读到数组中。boolean ready():如果这个流已准备好,返回True。OutputStreamWriter类的构造方法和方法:OutputStrea
18、mWriter(OutputStream out):构造一个OutputStreamWriter。OutputStreamWriter(OutputStream out, String enc):使用命名的字符编码构造一个OutputStreamWriter。void close():关闭流。void flush():刷新流。String getEncoding():得到这个流使用的字符编码的名称。void write(char cbuf, int off, int len):写字符数组的一部分。void write(int c):写一个字符。void write(String str, in
19、t off, int len):写一个字符串的一部分。【例15.10】 14字符流字符流FileReader FileReader(File file):构造一个FileReader。FileReader(FileDescriptor fd):从一个文件描述符构造一个FileReader。FileReader(String filename):从一个文件名构造一个FileReader。【例15.11】 15字符流字符流FileWriter FileWriter(File file):从File对象构造一个FileWriter。FileWriter(FileDescriptor fd):从文件描
20、述符构造一个FileWriter。FileWriter(String filename):从文件名构造一个FileWriter。FileWriter(String filename, boolean append):构造一进行附加的FileWriter。【例15.12】 16字符流字符流BufferedReader和BufferedWriter 这两个类对应的流使用了缓冲,能大大提高输入输出的效率。这两个也是过滤器流,常用来对InputStreamReader和OutputStreamWriter进行处理。【例15.13】 17字符流字符流CharArrayReader和CharArrayWr
21、iter CharArrayReader类的构造方法和方法如下:CharArrayReader(char buf):从给定的字符数组构造一个CharArrayReader。CharArrayReader(char buf, int offset, int length):同上。void close():关闭流。void mark(int readAheadLimit):在流中的当前位置加标记。boolean markSupported():如果这个流支持mark操作,那么返回True。int read():读取一个字符。int read(char b, int off, int len):将字
22、符读入数组的一部分。boolean ready():检查这个流是否已经准备好被读取。void reset():将流重设到最近的标记。long skip(long n):跳过n个字符。CharArrayWriter类的构造方法和方法如下:CharArrayWriter():构造一个CharArrayWriter。CharArrayWriter(int initialSize):构造一个具有给定初始大小的CharArrayWriter。void close():关闭流。void flush():刷新流。void reset():重设流。int size():得到缓冲区的当前大小。char toCh
23、arArray():得到输入数据的副本。String toString():将输入数据转换为字符串。void write(char c, int off, int len):将字符写到缓冲区中。void write(int c):将一个字符写到缓冲区中。void write(String str, int off, int len):将字符串的一部分写到缓冲区中。void writeTo(Writer out):将缓冲区的内容写到另一个字符流中。【例15.14】 18文件的随机访问文件的随机访问 31在java中,类RandomAccessFile 提供了随机访问文件的方法RandomAcce
24、ssFile(File file, String mode):构造一个随机访问文件流,file为被访问的文件对象,mode是用来指定存取的模式,mode可以为r(读)、w(写)或rw(读写)。RandomAccessFile(String name,String mode):构造一个随机访问文件流,以便访问由字符串name指定名字的文件,mode参数使用同上 32RandomAccessFile类提供的用来读取某种基本数据类型的数据或字符串的方法 boolean readBoolean()byte readByte()char readChar()double readDouble()floa
25、t readFloat()int readInt()long readLong()short readShort()String readLine() 33RandomAccessFile类提供的用来向文件中写入某种基本类型的数据或字符串的方法 void writeByte(byte b)void writeBytes(String s)void writeChar(char c)void writeChars(String s)void writeDouble(double d)void writeFloat(float f)void writeInt(int i)void writeLon
26、g(long l)void writeShort(short s)34和目前文件位置有关的方法 void seek(long pos):将文件指针移到pos(不可为负)的位置,相对于文件初始位置值(初始值为0)。long getFilePointer():得到目前文件指针的位置(相对于文件初始位置)。long length():得到文件的长度。int skipBytes( int n ):使文件指针向前移动指定的n个字节【例15.15】 19其他常用的流其他常用的流 33343132管道流 ZIP文件流DataInputStream和DataOutputStream 对象流 20综合案例综合案
27、例 【例15.16】下面的代码实现了一个简单的文件编辑器 import java.awt.*;import java.awt.event.*;import java.io.*;public class FileEdit extends WindowAdapter implements ActionListener,TextListener Frame f; TextArea ta1; Panel p1; TextField tf1; Button b1,b2,b3; FileDialog fd; File file1=null;public static void main(String ar
28、gs) (new FileEdit().display(); 21综合案例综合案例(续续)public void display() f = new Frame(FileEdit); f.setSize(680,400); f.setLocation(200,140); f.setBackground(Color.lightGray); f.addWindowListener(this); tf1 = new TextField(); tf1.setEnabled(false); tf1.setFont(new Font(Dialog,0,20); /设置文本行的初始字体 f.add(tf1,
29、North); ta1 = new TextArea(); ta1.setFont(new Font(Dialog,0,20); /设置文本区的初始字体 f.add(ta1); ta1.addTextListener(this); /注册文本区的事件监听程序 p1 = new Panel(); p1.setLayout(new FlowLayout(FlowLayout.LEFT); 22综合案例综合案例(续续) b1 = new Button(Open); b2 = new Button(Save); b3 = new Button(Save As); p1.add(b1); p1.add(
30、b2); p1.add(b3); b2.setEnabled(false); b3.setEnabled(false); b1.addActionListener(this); /注册按钮的事件监听程序 b2.addActionListener(this); b3.addActionListener(this); f.add(p1,South); f.setVisible(true);public void textValueChanged(TextEvent e) /实现TextListener接口中的方法,对文本区操作时触发 b2.setEnabled(true); b3.setEnabl
31、ed(true); 23综合案例综合案例(续续)public void actionPerformed(ActionEvent e) if (e.getSource()=b1) /单击打开按钮时 fd = new FileDialog(f,Open,FileDialog.LOAD); fd.setVisible(true); /创建并显示打开文件对话框if (fd.getDirectory()!=null) & (fd.getFile()!=null) tf1.setText(fd.getDirectory()+fd.getFile(); try /以缓冲区方式读取文件内容 file1 = n
32、ew File(fd.getDirectory(),fd.getFile(); FileReader fr = new FileReader(file1); BufferedReader br = new BufferedReader(fr); String aline; while (aline=br.readLine()!= null)/按行读取文本 ta1.append(aline+rn); fr.close(); br.close(); catch (IOException ioe) System.out.println(ioe); 24综合案例综合案例(续续) if (e.getSo
33、urce()=b2)|(e.getSource()=b3) /单击保存按钮时 if(e.getSource()=b3)|(e.getSource()=b2)&(file1=null) /单击SaveAs按钮时,或单击Save按钮且文件对象为空时 fd = new FileDialog(f,Save,FileDialog.SAVE); if(file1=null) fd.setFile(Edit1.txt); else fd.setFile(file1.getName(); fd.setVisible(true); /创建并显示保存文件对话框 if(fd.getDirectory()!=null
34、)&(fd.getFile()!=null) tf1.setText(fd.getDirectory()+fd.getFile(); file1 = new File(fd.getDirectory(),fd.getFile(); save(file1); 25综合案例综合案例(续续) else save(file1); public void save(File file1) try /将文本区内容写入字符输出流 FileWriter fw = new FileWriter(file1); fw.write(ta1.getText(); fw.close(); b2.setEnabled(f
35、alse); b3.setEnabled(false); catch (IOException ioe) System.out.println(ioe); public void windowClosing(WindowEvent e)System.exit(0); 26综合案例综合案例(续续)程序运行结果程序运行结果 27简答练习题353633343132利用输入输出流编写程序,实现文件拷贝的功能。利用输入输出流编写程序,实现文件拷贝的功能。 编写程序,实现在屏幕上显示文本文件的功能。编写程序,实现在屏幕上显示文本文件的功能。 有哪些常用的字节流和字符流,他们的主要区别是什么?有哪些常用的字
36、节流和字符流,他们的主要区别是什么? 对字节流和字符流进行读写操作的一般步骤是什么?对字节流和字符流进行读写操作的一般步骤是什么? File类有哪些构造方法和常用方法?类有哪些构造方法和常用方法? 编写程序,从键盘输入一串字符,从屏幕输出并将其存入编写程序,从键盘输入一串字符,从屏幕输出并将其存入a.txt文件中。文件中。 28【例15.1】标准输入输出举例 标准输入输出 输入输出流的分类import java.io.*;public class IODemopublic static void main(String args) throws IOException int b; int c
37、ount=0; while(b=System.in.read()!=-1)count+;System.out.print(char)b); System.out.println(); System.out.println(program end); 程序运行如下:输入:a,b,c,d 输出:a,b,c,d输入:Z 输出: program end 29【例15.2】对Test.txt及其上一级目录的File类对象进行操作 目录和文件管理目录和文件管理 File类 import java.io.*;public class fileTest /创建一个文件 public static void m
38、ain(String args) File f=new File(parentfileTest.txt); File f1=new File(newfileTest.txt); trySystem.out.println(f.getParent(); System.out.println(f.getName(); System.out.println(f1.getPath(); System.out.println(f1.getAbsolutePath();catch(Exception e)e.printStackTrace(); 程序运行结果程序运行结果 30【例15.3】建立 test.
39、txt 文件对象,判断是否存在,如果不存在就创建之 import java.io.*;public class CreateNewFilepublic static void main(String args)File f=new File(test.txt);tryif(!f.exists()f.createNewFile();elseSystem.out.println(exists);catch(Exception e)e.printStackTrace();程序运行结果程序运行结果目录和文件管理目录和文件管理 File类 31【例15.4】创建文件夹Dir以及文件夹dir/cdir。目
40、录和文件管理目录和文件管理 File类 import java.io.*;public class CreateDir public static void main(String args) File f=new File(test.txt); File f1=new File(Dir); File f2=new File(dir/cdir); File f3=new File(newTest.txt); try f.renameTo(f3);/把test.txt改名为newTest.txt f1.mkdir(); /创建目录Dir f2.mkdirs(); /创建目录dir及其子目录cdi
41、r catch(Exception e)e.printStackTrace(); 程序运行结果程序运行结果 32【例15.5】使用File类的方法获取文件file.txt的属性信息 目录和文件管理目录和文件管理 File类的应用 import java.io.*;public class filepublic static void main(String args)File fl = new File(file.txt);System.out.println(The file is exist? +fl.exists();System.out.println(The file can wri
42、te? +fl.canWrite();System.out.println(The file can read? +fl.canRead();System.out.println(The file is a file? +fl.isFile();System.out.println(The file is a directory? +fl.isDirectory();System.out.println(The files name is: +fl.getName();System.out.println(The files all path is: + fl.getAbsolutePath(
43、);System.out.println(The files length is +fl.length();程序运行结果程序运行结果 33【例15.6】列出Dir目录下的所有文件和目录(String list( ),最后修改时间;若为目录则在其后面标出,若为文件,则在其后面标出文件长度(提示:方法long lastModified()能够返回自1970.1.1起 到最后修改时间之间的秒数) import java.io.*;import java.util.*;public class testDir public static void main(String args) File f=ne
44、w File(Dir); String listAll=null; File temp=null; try listAll=f.list(); for(int i=0;ilistAll.length;i+) temp=new File(listAlli); System.out.print(listAlli+t); if(temp.isDirectory()System.out.print(tt); else System.out.print(temp.length()+t);System.out.println(new Date(temp.lastModified();catch(Excep
45、tion e)e.printStackTrace();目录和文件管理目录和文件管理 File类的应用 程序运行结果程序运行结果 34字节流字节流【例15.7】将FileIO.java复制为FileExam.java.bak import java.io.*;public class FileIOpublic static void main(String args) FileInputStream inFile=null; FileOutputStream outFile=null; tryinFile=new FileInputStream(FileIO.java); outFile=new
46、 FileOutputStream(FileExam.java.bak); int date; while(date=inFile.read()!=-1)outFile.write(date); catch(FileNotFoundException e)System.out.println(e.getMessage(); catch(IOException e)System.out.println(e.getMessage(); finallyif(inFile!=null)tryinFile.close();catch(IOException e) if(outFile!=null)try
47、outFile.close();catch(IOException e) 程序运行结果程序运行结果【解题分析解题分析】以下问题的求解过程可分解如下:以下问题的求解过程可分解如下:先打开文件先打开文件FileExam.java用用read()将其内容逐字节读取出来将其内容逐字节读取出来(如果返回值为如果返回值为-1,则,则表明已到达文件尾端表明已到达文件尾端)再用再用write()将读出的字节逐一写入另一个文件将读出的字节逐一写入另一个文件FileExam.java.bak中中若文件无法打开若文件无法打开(例如例如FileExam.java不存在不存在)或无法生成或无法生成(FileExam.j
48、ava.bak),则抛出,则抛出FileNotFoundException异常,异常,若读写出错,则抛出若读写出错,则抛出IOException异常。异常。最后,在最后,在finally中关闭文件。中关闭文件。 35【例15.8】程序读入文件ByteIO.java,将其内容写入内存中(一个字节数组),接着转换为String对象,并将该String对象内的令牌解析出来 字节流字节流import java.io.*;import java.util.*;public class ByteIOpublic static void main(String args) tryFile inFile=ne
49、w File(FileIO.java); FileInputStream inData=new FileInputStream(inFile); ByteArrayOutputStream dataArray=new ByteArrayOutputStream(); int data; while(data=inData.read()!=-1)dataArray.write(data); inData.close(); String dataStr=dataArray.toString(); StringTokenizer tokens=new StringTokenizer(dataStr)
50、; while(tokens.hasMoreTokens()System.out.println(tokens.nextToken(); catch(IOException e)System.out.println(e.getMessage(); 程序运行结果程序运行结果 36【例15.9】文件拷贝的缓冲改进 字节流字节流/文件拷贝的缓冲改进import java.io.*;public class Copy public static void main(String args) BufferedInputStream bis=null; BufferedOutputStream bos=n