实验6 文件IO练习.docx
《实验6 文件IO练习.docx》由会员分享,可在线阅读,更多相关《实验6 文件IO练习.docx(46页珍藏版)》请在冰豆网上搜索。
![实验6 文件IO练习.docx](https://file1.bdocx.com/fileroot1/2022-11/24/f7203b7d-91f2-4cd3-919d-85f09663f49e/f7203b7d-91f2-4cd3-919d-85f09663f49e1.gif)
实验6文件IO练习
实验6文件I/O练习
一.实验目的
1.通过阅读本课件知识点和例题,了解文件I/O的类型、原理、程序资源(类族)和编程方法。
2.参考本课件对文件I/O类方法的描述及其给出的例题,寻找解决方案并编写程序,实现所要求的输入输出功能,以加深对本章内容的理解、提高文件I/O的实际运用能力。
二.知识点和例题
1.文件I/O的概念和分类
⑴什么是文件
文件是存储于外存储器(如硬盘、U盘)上的一组信息的集合。
文件在外存储器上以树形层次结构存储,由操作系统管理。
例如在Windows资源管理器上“我的电脑”是树根,文件是树叶,期间有驱动器和一系列文件夹作为树杈。
文件由文件名以及表示在树上位置的一个路径来标识,文件名由主名和表示文件类型的扩展名构成,例如:
C:
\DocumentsandSettings\Java\MyProg.java
盘符路径文件名扩展名
⑵何谓及如何实现文件I/O
内存与文件的信息交换称为文件I/O,即从文件输入(I)和向文件输出(O)。
广义的文件也包括I/O设备,如打印机等。
这些信息交换由程序来控制,不同的程序设计语言有不同的文件I/O控制方法。
如C用fscanf/fprintf、fread/fwrite等几套函数;C++用fstream中的ifstream/ofstream对象;C#用stream类及其下面的一系列子类;Java则用InputStream/OutputStream、Reader/Writer类族来实现文件I/O。
⑶文件的类型
要正确实现文件I/O,必须根据文件的性质及I/O方式将文件分为几种不同的类型:
文本文件——保存以ASCII、UNICODE等编码方式存储的文本。
二进制文件——保存以二进制方式存储的数据,如整数、浮点数、声音、图像等。
顺序读写文件——以顺序读写方式打开的文件,按照字节或进出数据的顺序进行读写。
随机读写文件——以随机读写方式打开的文件,按照数据在文件中的位置(字节序号)进行定长数据的读写。
⑷流的概念
流(stream)是一组有序的、有起点和终点的字节集合,是对输入输出的抽象。
引入流的目的是使I/O操作与具体设备无关。
对流的操作以字节为单位进行,并常常使用缓冲区(buffer)技术,这是因数据在内存中流动的速度要比文件存取的速度快得多,而文件存取的时间又与存取的频率成正比,为减小存取频率,系统让I/O先对缓冲区进行,当缓冲区空、满或文件关闭时,才发生物理的读入或写出。
⑸字节流和字符流
字节流是Java文件I/O的基本类型,即以字节为单位的、顺序方式的输入和输出。
根据数据源、是否使用缓冲区,以及一次输入输出数据的类型等因素,在这种基本类型之上又派生出一系列子类型。
字符流是以字符为单位的I/O。
由于Java使用的是UNICODE编码,因此单次输入输出的若是一个字节,则汉字等非英文字符将无法正确显示。
根据是否有缓冲区等因素,字符流亦派生出一系列子类型。
⑹操作方式和类族
流操作方式
字节流类族
字符流类族
不使用缓冲区
InputStream
OutputStream
Reader
Writer
使用缓冲区
BufferedInputStream
BufferedOutputStream
FileReader
FileWriter
将字节流转化为基本类型流
DataInputStream
DataOutputStream
将字节流转化为字符流
InputStreamReader
OutputStreamWriter
将流转化为String
PrintStream
PrintWriter
将字节流转化为对象流
ObjectInputStream
ObjectOutputStream
⑺关于序列化
在面向对象程序中,有时我们需要把对象的数据(往往由各种不同的类型的数据项组成)按照原来的结构一并向文件写入,或从文件读出到对象中,并且将一个个对象的值首尾串接构成一个序列,怎样写入,就怎样读出,这种I/O方式称为序列化(serialization)。
由于不同类对象的数据结构不同,因此任何打算序列化的对象,其所属类都必须实现java.io.Serializable接口规范。
⑻文件I/O作业的一般流程
读操作(I)
写操作(O)
1
importjava.io.*;
importjava.io.*;
2
try{
打开(open)一个流
try{
打开(open)一个流
3
while(还有数据){
读出数据;
//其它处理
}
while(还有数据){
写入数据;
//其它处理
}
4
关闭(close)打开的流
}catch(IOExceptione){}
关闭(close)打开的流
}catch(IOExceptione){}
2.File类和JfileChooser类
⑴File类概述
一个文件的信息分外部信息和内部信息,外部信息除了路径、文件名和扩展名之外,还包括是否只读、是否隐藏等属性信息;内部信息则是文件中的内容。
File类封装了文件的外部信息,并提供了对它的一系列操作,如修改文件属性、重命名等。
除此之外,File类的对象还用作流方法的参数,用来将流对象与物理文件绑定,例如:
Filef=newFile("e:
\\","06143.txt");
FileReaderin=newFileReader(f);
⑵File类的方法
①构造方法
方法原型
功能说明和实例
File(Fileparent,Stringchild)
利用File对象与字符串构成的路径创建一个File对象,例如:
Filed=newFile("e:
\\folder");
Filef=newFile(d,"me.txt");
File(Stringpathname)
利用字符串指定的路径和文件名创建一个File对象,例如:
Filef=newFile("e:
\\me.txt");
File(Stringparent,Stringchild)
利用字符串指定的路径和文件名创建一个File对象,例如:
Filef=newFile("e:
\\","me.txt");
File(URIuri)
利用URI对象创建一个File对象
②测试文件状态
方法原型
功能说明和实例
booleanexists()
测试File对象代表的文件是否存在,例如:
if(f.exists()){in=newFileReader(f);…}
booleanisFile()
测试File对象是否代表文件
booleanisDirectory()
测试File对象是否代表文件夹
booleanisAbsolute()
测试File对象代表的是否为绝对路径
booleanisHidden()
测试File对象代表的是否为隐藏文件
booleancanRead()
测试File对象代表的文件是否为只读
booleancanWrite()
测试File对象代表的文件是否可写
③测试文件属性
方法原型
功能说明和实例
StringgetName()
返回File对象代表的文件的名称,例如:
Filef=newFile("e:
\\06143.txt");
System.out.print(f.getName());//打印“06143.txt”
longlength()
返回File对象代表的文件的大小,例如:
Filef=newFile("e:
\\06143.txt");
System.out.print(f.length());//打印“2175”
longlastModified()
返回File对象代表的文件的最近一次修改时间,可通过Date转换为可读格式
StringgetParent()
返回File对象代表的文件的上层文件夹
FilegetParentFile()
返回File对象代表的文件的上层文件夹相关的File对象
④测试文件路径
方法原型
功能说明和实例
StringgetPath()
返回File对象所代表文件的路径总称,如果创建时未设置,则返回文件名称
StringgetAbsolutePath()
返回File对象所代表文件的绝对路径:
Filef=newFile("e:
\\06143.txt");
System.out.println(f.getAbsolutePath());
StringgetCanonicalPath()
返回File对象所代表文件的规范路径:
Filef=newFile("e:
\\06143.txt");
try{
System.out.println(f.getCanonicalPath());
}catch{}//必须包含在try…catch块中
FilegetAbsoluteFile()
以File形式返回File对象所代表文件的绝对名称
FilegetCanonicalFile()
以File形式返回File对象所代表文件的规范名称
⑤设置文件属性
方法原型
功能说明和实例
booleanrenameTo(Filedest)
将File对象代表的文件更名为dest代表的文件的名称,例如:
Filef=newFile("e:
\\06143.txt");
f.renameTo(newFile("e:
\\123.txt"));
System.out.print(f.getName());
经过这一操作后,磁盘上的文件被改名,但对象f的值不变
booleansetReadOnly()
将File对象代表的文件更改为具有只读属性
booleansetLastModified(longtime)
设置File对象所代表的文件的最近一次修改时间
⑥创建和删除文件夹
方法原型
功能说明和实例
booleanmkdir()
创建一个文件夹,并以File对象中的文件名作为文件夹名,例如:
Filef=newFile("e:
\\Java2");
f.mkdir();//在e:
盘根目录下创建文件夹"Java2"
booleanmkdirs()
创建一个包含有上层文件夹的文件夹,并以File对象中的路径作为文件夹名,例如:
Filef=newFile("e:
\\Java\\workspace");
f.mkdirs();//在e:
盘下创建\Java\workspace
booleandelete()
删除File对象代表的文件或文件夹,例如:
Filef=newFile("e:
\\Java2");
f.delete();
voiddeleteOnExit()
程序结束时删除File对象代表的文件或文件夹
⑦列出文件
方法原型
功能说明和实例
String[]list()
返回File对象所代表的文件夹下的文件和文件夹
String[]list(FilenameFilterfilter)
返回File对象代表的文件夹下、符合给定文件名约束条件的文件和文件夹
File[]listFiles()
返回File对象代表的文件夹下所有File对象
File[]listFiles(FileFilterfilter)
返回File对象代表的文件夹下符合给定内部信息约束条件的File对象
File[]listFiles(FilenameFilterfilter)
返回File对象代表的文件夹下符合给定文件名约束条件的File对象
staticFile[]listRoots()
列出所有可取得的文件系统的根目录
⑶JFileChooser类概述
JFileChooser类是Swing类库中的一个成员,Swing类库是Sun开发的一个图形用户界面(GUI)工具包,将在“用户界面”一章详细介绍,这里引入JFileChooser类的目的是想配合File类,让用户在一个可视化的环境下对所需文件进行选择,这样,作业Student中的文件“06143.txt”也就不必写入源程序了。
要使用JFileChooser类,需要在源文件头部使用以下语句:
importjavax.swing.JFileChooser;
⑷JFileChooser的方法
①构造方法
方法原型
功能说明
JFileChooser()
在默认目录下选择文件
JFileChooser(FilecurrentDirectory)
在File代表的目录下选择文件
JFileChooser(FilecurrentDirectory,
FileSystemViewfsv)
利用FileSystemView在当前目录下选择文件
JFileChooser(FileSystemViewfsv)
利用FileSystemView选择
JFileChooser(StringcurrentDirPath)
在指定目录下选择文件
JFileChooser(StringcurrentDirPath,
FileSystemViewfsv)
利用FileSystemView在指定的目录下选择文件
②打开窗口
方法原型
功能说明
intshowOpenDialog(Componentparent)
打开一个“Open”文件对话框
intshowSaveDialog(Componentparent)
打开一个“Save”文件对话框
intshowDialog(Componentparent,
StringapproveButtonText)
自定义Open或Save按钮文本
showOpenDialog的返值及其意义:
JFileChooser.APPROVE_OPTION用户点击取消以外的按钮
JFileChooser.CANCEL_OPTION用户点击取消按钮
JFileChooser.ERROR_OPTION发生错误或不正常关闭
③选择文件
方法原型
功能说明
FilegetSelectedFile()
返回被选中的文件
File[]getSelectedFiles()
返回所有被选中的文件
booleanisMultiSelectionEnabled()
返回是否允许多重选择
voidsetMultiSelectionEnabled(booleanb)
设置是否允许多重选择
④设置外观
方法原型
功能说明
voidsetApproveButtonText
(StringapproveButtonText)
设置“确定”按钮的文字内容
voidsetApproveButtonToolTipText
(StringToolTipText)
设置“确定”按钮的ToolTip文字
FilegetCurrentDirectory()
返回代表当前目录的对象
StringgetDialogTitle()
返回文件设置窗口标题
⑸JFileChooser类应用实例
importjava.io.*;
importjavax.swing.JFileChooser;
publicclassUseJFileChooser{
publicstaticvoidmain(String[]args){
Filef=newFile("我的文档");
JFileChooserfileChooser=newJFileChooser(f);
if(fileChooser.showOpenDialog(null)==FileChooser.APPROVE_OPTION){
f=fileChooser.getSelectedFile();
System.out.print("您选择的文件是:
"+f.getPath());
}
else{
System.out.print("用户取消");
}
}
}
3.字节流类族
⑴层次结构图
⑵抽象基类
①InputStream抽象类
方法
功能
InputStream()
构造方法:
创建字节输入流对象
intavailable()
测试有多少字节可供读取
abstractintread()
抽象方法:
读取一个字节
intread(byte[]b)
将读取的字节存入byte数组
intread(byte[]b,intoff,intlen)
将自off读取len个字节存入数组
longskip(longn)
读标志从数据源跳过n个字节
booleanmarkSupported()
测试可否在数据源中加标记
voidmark(intreadLimit)
在数据源的给定位置加标记
voidreset()
重置上次加注的标记
voidclose()
关闭数据源并释放资源
②OutputStream抽象类
方法
功能
OutputStream()
构造方法:
创建字节输出流对象
abstractvoidwrite(intdata)
抽象方法:
写出data中1字节数据
voidwrite(byte[]b)
将byte数组中的数据写出
voidwrite(byte[]b,intoff,intlen)
从off开始写出数组中len字节数据
voidflush()
清空数据源对象
voidclose()
关闭数据源
⑶文件字节流子类
这组子类分别继承自抽象基类InputStream和OutputStream,并将外部文件作为流的来源(数据源),即从文件读,向文件写。
文件名可由已创建的File对象给出,也可由一个字符串给出,例如文件名为1.txt,则:
Filefi=newFile("e:
\\1.txt");
FileInputStreamfis=newFileInputStream(fi);
或:
FileInputStreamfis=newFileInputStream("e:
\\1.txt");
在创建该对象的同时,文件也被打开。
1FileInputStream子类
方法
功能
FileInputStream(Filefile)
创建以File对象作为数据源的对象
FileInputStream(Stringname)
创建以文件name作为数据源的对象
intavailable()
测试有多少字节可以从文件读取
intread()
从给定文件读取一个字节
intread(byte[]b)
读取数据放入byte数组,并返回字节数
intread(byte[]b,intoff,intlen)
读取len个字节存入byte数组off位置
longskip(longn)
读标志从数据源跳过n个字节
booleanmarkSupported()
测试可否在数据源中加注标记
voidmark(intreadLimit)
在数据源的给定位置加注标记
voidreset()
重置上次加注的标记
voidclose()
关闭数据源并释放资源
②FileOutputStream子类
方法
功能
FileOutputStream(Filefile)
创建以File作为数据源的对象
FileOutputStream(Stringname)
创建以name作为数据源的对象
FileOutputStream(Stringname,
booleanappend)
创建以name作为数据源的对象并指出是否以追加的方式写出
voidwrite(intdata)
向给定文件写出一个字节
voidwrite(byte[]b)
将byte数组中的数据写到文件
voidwrite(byte[]b,intoff,intlen)
从off开始写出数组len字节数据
voidflush()
清空数据源对象
voidclose()
关闭数据源
程序实例:
importjava.io.*;
publicclassUseFileInputStream{
publicstaticvoidmain(String[]args){
Filefi=newFile("e:
\\06143.txt");
Filefo=newFile("d:
\\06143.txt");
try{
FileInputStreamfis=newFileInputStream(fi);
FileOutputStreamfos=newFileOutputStream(fo);
intch,n=fis.available();
for(inti=0;ich=fis.read();
fos.write(ch);
}
fis.close();
fos.close();
}
catch(IOExceptione){
System.err.println(e.getMessage());
}
}
}
⑷数组字节流子类
这组子类分别继承自InputStream和OutputStream,但使用一个字节数组byte[]作为流的来源,该字节数组在ByteArrayInputStream中是作为构造方法参数表中的一个参数被引用;而在ByteArrayOutputStream中,则是作为类的属性被封装,即从给定的一个byte数组读;向封装在对象内部的一个byte数组写。
对数组进行I/O的目的是:
因为数组在内存中,I/O速度远比文件快得多,当程序需要高速度、非永久性的I/O时,数组是最好的选择。
①ByteArrayInputStream子类
方法
功能
ByteArrayInputStream(byte[]d)
创建以byte数组作为数据源的对象
ByteArrayInputStream(byte[]d,
intoff,intlen)
创建以byte数组作为数据源的对象,数据的存储从off开始,使用len个字节
intavailable()
测试有多少字节可以从byte数组中读取
intread()
从byte数组读取一个字节
intread(byte[]b)
从byte数组读取数据到另一个byte数组
intread(byte[]b,
intoff,i