350 likes | 503 Views
项目七 输入输出æµå’Œæ–‡ä»¶æ“作. ä¿¡æ¯å·¥ç¨‹ç³» æœå‘ç„¶. æŠ€èƒ½ç›®æ ‡ èƒ½æ ¹æ®æ•°æ®çš„类型选择相应的输入输出æµè¿›è¡Œæ•°æ®çš„读写æ“作,能通过 File 类对文件进行æ“作。 çŸ¥è¯†ç›®æ ‡ 了解æµçš„æ¦‚念; 了解输入输出æµçš„基本知识; 了解文件的基本知识; 掌æ¡å¸¸ç”¨çš„å—节æµå’Œå—符æµåŠå…¶æ–¹æ³•ï¼› æŽŒæ¡ File 类的使用; 项目任务 本项目完æˆè¾“入输出æµå’Œæ–‡ä»¶æ“ä½œçš„åŸºæœ¬åŠŸèƒ½ï¼Œè¦æ±‚能选择åˆé€‚的输入输出æµå¯¹æ•°æ®è¿›è¡Œè¯»å†™æ“作,能通过 File 类对文件进行æ“作。. 任务一 å—节输入输出æµ. â‘ è¯»å–æ–‡ä»¶å†…容。 import java.io.FileInputStream;
E N D
项目七 输入输出流和文件操作 信息工程系 杜向然
技能目标 • 能根据数据的类型选择相应的输入输出流进行数据的读写操作,能通过File类对文件进行操作。 知识目标 • 了解流的概念; • 了解输入输出流的基本知识; • 了解文件的基本知识; • 掌握常用的字节流和字符流及其方法; • 掌握File类的使用; 项目任务 • 本项目完成输入输出流和文件操作的基本功能,要求能选择合适的输入输出流对数据进行读写操作,能通过File类对文件进行操作。
任务一 字节输入输出流 • ①读取文件内容。 • import java.io.FileInputStream; • import java.io.DataInputStream; • import java.io.EOFException; • public class InputStreamTest • { • public static void main(String[ ] args) throws Exception • { • FileInputStream fis=new FileInputStream("test1.txt"); //创建字节输入流对象 • DataInputStream dis=new DataInputStream(fis); //创建过滤器输入流对象
try{ • while (true) • { • System.out.println(dis.readInt( )); • } • } • catch(EOFException e){ • dis.close( ); • fis.close( ); • } • } • }
相关知识 • 1.什么是流? • 流是一个抽象的概念。程序中处理的任何信息都是数据,当Java程序需要对数据进行操作时,必须与数据源联系起来,或者从数据源读取数据,或者往数据源写入数据。 • 流可分为两类:输入流和输出流。用户可以从输入流中读取数据,但不能写数据。相反,对输出流,只能向其中写入数据,而不能读数据。
按照处理数据类型的不同,流可以分为字节流和字符流。字节流以字节为基本单位进行处理,也称为原始数据,适合7位ASCII码的操作;而字符流以字符为基本单位进行处理,用2字节的Unicode作为编码。按照处理数据类型的不同,流可以分为字节流和字符流。字节流以字节为基本单位进行处理,也称为原始数据,适合7位ASCII码的操作;而字符流以字符为基本单位进行处理,用2字节的Unicode作为编码。 • 2. InputStream类和OutputStream类 • 抽象类InputStream和OutputStream是所有字节流的基类 ,二者都是抽象类,它们分别提供了输入和输出处理的基本接口,并且都分别实现了其中的某些方法。
InputStream中所提供的方法主要有: • 从流中读取数据 • int read() • 从输入流中读取一个字节,返回范围在0到255 之间的一个整数,该方法的属性为 abstract,必须为子类所实现。 • int read(byte b[]) • 从输入流中读取长度为b.length的数据,写入字节数组b,并返回读取的字节数。 • int read (byte b[], int off, int len) • 从输入流中读取长度为len的数据,写入字节数组b中从索引off开始的位置,并返回读取的字节数。 • 对于以上方法,如果达到流的末尾位置,则返回-1表明流的结束。 • int available() • 返回从输入流中可以读取的字节数。
关闭流并且释放与该流相关的系统资源 • close() • 关闭流可以通过调用方法close()显式进行,也可以由运行时系统在流对象进行垃圾收集时隐式进行。 • 使用输入流中的标记 • void mark(int readlimit) • 在输入流的当前读取位置作标记,从该位置开始读取readlimit所指定的数据后,标记失效。 • void reset() • 重置输入流的读取位置为方法mark()所标记的位置。 • boolean markSuppont() • 确定输入流是否支持方法mark()和reset()。
InputStream中有一个子类FilterInputStream,它就是一个典型的过滤器输入流。filter这个单词本身就是过滤器的意思,源于和滤水器的类比。我们经常把一个滤水器安放在水管和水龙头之间,滤掉杂质。而在程序中,我们把流过滤器安放在数据源和最终目的地之间,对数据执行某种算法。流过滤器不仅可以去掉程序员不想要的数据,还可以增加数据或其他注解,甚至可以提供一个和初始流完全不同的流。InputStream中有一个子类FilterInputStream,它就是一个典型的过滤器输入流。filter这个单词本身就是过滤器的意思,源于和滤水器的类比。我们经常把一个滤水器安放在水管和水龙头之间,滤掉杂质。而在程序中,我们把流过滤器安放在数据源和最终目的地之间,对数据执行某种算法。流过滤器不仅可以去掉程序员不想要的数据,还可以增加数据或其他注解,甚至可以提供一个和初始流完全不同的流。 • FilterInputStream 类的构造方法为FilterInputStream(InputStream),在指定的输入流之上,创建一个输入流过滤器。FilterInputStream的常用的子类如下: • BufferedInputStream • 缓冲区对数据的访问,以提高效率。
DataInputStream • 从输入流中读取基本数据类型,如int、float、double或者甚至一行文本。 • LineNumberInputStream • 在翻译行结束符的基础上,维护一个计数器,该计数器表明正在读取的是哪一行。 • PushbackInputStream • 允许把数据字节向后推到流的首部。 • DataInputStream的readInt()方法每次从输入流读入四个字节,然后将它们翻译成一个int数据。在题目中,我们循环调用这个方法,直到读到文件末尾,该方法会抛出EOFException异常,因此我们将相关语句放在try语句当中进行。
(2)OutputStream类 • 它负责将信息送至输出目标中,这个类也有很多子类,并且也不直接使用,而是对它进行包装后,使用各种过滤器类。 • 除了构造方法外,OutputStream中封装的方法主要实现对输出数据的支持。 • 输出数据 • void write(int b) • 将指定的字节b写入输出流。
void write(byte b[]) • 把字节数组b中的b.length个字节写入输出流。 • void write(byte b[], int off, int len) • 把字节数组b中从索引off开始的len个字节写入输出流。 • flush() • 刷新输出流,并输出所有被缓存的字节。 • 关闭流 • 与类InputStream类似,可以用方法close()显式地关闭输出流,也可以由运行时系统在对流对象进行垃圾收集时隐式关闭输出流。
我们选择DataOutputStream作为与FileOutputStream类对象fos配合使用的过滤器流。我们选择DataOutputStream作为与FileOutputStream类对象fos配合使用的过滤器流。 • DataOutputStream的writeInt(int i)方法每次将一个 int 值以 4-byte 值形式写入字节输出流中,先写入高字节,后写入低字节。在题目中,我们循环10次调用这个方法,将0至9十个数字写入文件。该方法会抛出IOException异常,因此我们在写main方法的时候同时声明。
任务二 字符输入输出流 • import java.io.*; • public class ReaderTest{ • public static void main(String args[]) throws IOException{ • String s; • FileInputStream fis; • InputStreamReader isr; //声明字符输入流对象 • BufferedReader br; //声明过滤器输入流对象 • fis=new FileInputStream("test2.txt");
isr=new InputStreamReader(fis); • br=new BufferedReader(isr); • while((s=br.readLine())!=null) • System.out.println("现在读的是:"+s); • fis.close(); • isr.close(); • br.close(); • } • }
相关知识 • 1.Reader类 • Reader的常用子类及其功能如下: • CharArrayReader • 从字符数组中读取数据。 • InputStreamReader • FileReader(InputStreamReader的子类) • 从本地文件系统中读取字符序列。
StringReader • 从字符串中读取字符序列。 • PipedReader • 从线程管道中读取字符序列。 • Reader类的主要方法有: • (1)读取字符 • public int read() throws IOException • 读取一个字符。 • public int read(char cbuf[]) throws IOException • 读取一系列字符到数组cbuf[]中。
public abstract int read(char cbuf[],int off,int len) throws IOException • 读取len个字符到数组 cbuf[]的索引off处,该类必须被子类实现。 • (2)标记流 • pulbic boolean markSupported() • 判断当前流是否支持作标记。 • public void mark(int readAheadLimit) throws IOException • 给当前流作标记,最多支持readAheadLimit个字符的回溯。 • public void reset() throws IOException • 将当前流重置到作标记处。 • (3)关闭流 • public abstract void close() throws IOException • 该方法必须被子类实现。
常见的面向字符流的过滤器流有: • BufferedReader • 缓冲数据的访问,以提高效率。 • LineNumberReader(BufferedReader的子类) • 维护一个计数器,该计数器表明正在读取的是哪一行。 • FilterReader(抽象类) • 提供一个类,创建过滤器时可以扩展这个类。
我们选择BufferedReader作为与InputStreamReader类对象isr配合使用的过滤器流。我们选择BufferedReader作为与InputStreamReader类对象isr配合使用的过滤器流。 • BufferedReader的readLine()方法每次可以读取一个文本行,效率比较高,这也是我们选择BufferedReader的一个原因。该方法也会抛出IOException异常,因此我们在写main方法的时候同时声明。
2.Writer类 • Writer类的主要方法有: • (1)向输出流写入字符 • public void writer(int c) throws IOException • 将整数值C的低16位写入输出流。 • public void writer(char cbuf[]) throws IOException • 将字符数组cbuf[]中的字符写入输出流。 • public abstract void write(char cbuf[],int off,int len) throws IOException • 将字符数组cbuf[]中从索引为off的位置处开始的len个字符写入输出流。
public void write(String str) throws IOException • 将字符串str中的字符写入输出流。 • public void write(String str,int off,int len) throws IOException • 将字符串str中从索引off开始处的len个字符写入输出流。
(2)flush() • 刷新输出流,并输出所有被缓存的字节。 • (3)关闭流 • public abstract void close() throws IOException该方法必须被子类实现。
选择PrintWriter作为与FileWriter类对象fw配合使用的过滤器流。选择PrintWriter作为与FileWriter类对象fw配合使用的过滤器流。 • PrintWriter的println()方法每次可以向流中写入一个文本行,它与上述的BufferedReader的readLine()方法是对应的,使用起来比较方便,这也是我们选择PrintWriter的一个原因。
任务三 文件操作 • class TestFileMethods{ • public static void main(String args[]){ • File f=new File("test1.txt"); //创建文件对象 • System.out.println("exist? "+f.exists()); • System.out.println("name: "+f.getName()); • System.out.println("path: "+ f.getPath()); • System.out.println("absolutepath: "+f.getAbsolutePath()); • System.out.println("parent"+f.getParent()); • System.out.println("is a file? "+f.isFile()); • …… • } • }
相关知识 • 1.File类 • 通过File类提供的方法,我们只能对文件本身的一些属性进行操作 • 2.File类方法 • (1)文件的生成 • File类中提供了三种构造方法可用来生成一个文件或目录。 • public File(String path):path可包含路径及文件名。 • public File(String path,String name):path代表路径,name代表文件名。 • public File(File dir,String name):dir代表File类型的路径,name代表文件名。 • (2)文件名的处理 • String getName():得到一个文件的名称(不包括路径)。 • StringgetPath():得到一个文件的路径名。 • String getAbsolutePath():得到一个文件的绝对路径名。 • String getParent():得到一个文件的上一级目录名。 • String renameTo(File newName) :重新命名当前文件。
(3)文件属性测试 • boolean exists():测试当前File对象所指示的文件是否存在。 • boolean canWrite():测试当前文件是否可写。 • boolean canRead):测试当前文件是否可读。 • boolean isFile():测试当前文件是否是文件。 • boolean isDirectory():测试当前文件是否是目录。 • (4)普通文件信息和工具 • long lastModified():到文件最近一次修改的时间。 • long length():得到文件的长度,以字节为单位。 • Boolean delete():删除当前文件。 • (5)目录操作 • boolean mkdir():根据当前对象生成一个由该对象指定的路径。 • String list():列出当前目录下的文件。 • 在前面具体实现的程序中,我们通过构造方法File(“test1.txt”)把文件对象f和文件test1.txt联系在一起,后面通过f调用File类的各种方法,从而得到test1.txt的各种属性。
3.文件的顺序处理 • 前面提到的输入输出流,也有基于文件处理的,其中FileInputStream和FileOutputStream就是用来专门进行文件的输入和输出处理。在这两个类里,分别提供了一些方法,用来对本地主机上的已经打开的文件进行顺序的读和写操作。 • 类 FileInputStream 用于读取诸如图像数据之类的原始字节流,它的常用方法如下: • int available() • 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。 • void close() • 关闭此文件输入流并释放与此流有关的所有系统资源。 • protected void finalize() • 确保在不再引用文件输入流时调用其close方法。
int read() • 从此输入流中读取一个数据字节。 • int read(byte[] b) • 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 • int read(byte[] b, int off, int len) • 从此输入流中将最多len个字节的数据读入一个 byte 数组中。 • long skip(long n) • 从输入流中跳过并丢弃n个字节的数据。
4.随机访问文件 • 类RandomAccessFile称为随机访问文件类,它提供了对文件进行随机访问的支持。它是直接继承类Object,并且实现了接口DataInput和接口DataOutput,DataInput中定义的方法主要用来从流中读取基本类型的数据、读取一行数据、或者读取指定长度的字节数;DataOutput中定义的方法主要用来向流中写入基本类型的数据、或者写入一定长度的字节数组。
RandomAccessFile类是通过指针实现对文件的随机访问的,文件位置指针遵循下面的规律:RandomAccessFile类是通过指针实现对文件的随机访问的,文件位置指针遵循下面的规律: • ·新建RandomAccessFile对象的文件位置指针位于文件的开头处; • ·每次读写操作之后,文件位置的指针都相应后移读写的字节数; • ·可以通过getFilePointer方法来获得文件位置指针的位置,通过seek方法来设置文件指针的位置。 • RandomAccessFile类,既可以充当输入也可充当输出流,其构造方法如下: • RandomAccessFile (“路径+文件名”, String“rw”/“r”)两个参数,第二个参数表示创建模式:“rw”代表写流,“r”代表读流。 • RandomAccess类的其他常用方法还有: • long getFilePointer():获取文件指针的位置。 • long length():获取文件的长度。
int read():从文件中读取一个字节。 • int read(byte[] b):从文件中读取b.length个字节的数据并保存到数组b中。 • int read(byte[] b,int off,int len):从文件中读取len个字节的数据并保存到数组b的指定位置中。 • boolean readBoolean():从文件中读取一个boolean值。 • byte readbyte():从文件读取一个字节。 • char readChar():从文件读取一个字符。 • double readDouble():从文件中读取一个double值。 • float readFloat():从文件中读取一float值。 • void readFully(byte[] b):从文件中的当前指针位置开始读取b.length个字节的数据到数组b中。
String readLine():从文件中读取一个字符串。 • long readLong():从文件中读取一个long值。 • short readShort():从文件中读取一个short值。 • String readUTF():从文件中读取一个字符串。 • void seek(long pos):指定文件指针在文件中的位置。 • void setLength(long newLength):设置文件的长度。 • int skipBytes(int n):在文件中跳过指定的字节数。
void write(byte[] b):向文件中写入一个字节数组。 • void write(byte[] b,int off,int len):向文件中写入数组b中从off位置开始长度为len的字节数据。 • void write(int b):向文件中写入一个int值。 • void writeBoolean(boolean v):向文件中写入一个boolean值。 • void writeByte(int v):向文件中写入一个字节。 • void writeByte(String s):向文件中写入一个字符串。
动手练习 • 练习目的: • 1.理解Java中输入输出流的概念。 • 2.掌握常用的输入输出类的功能及其读写方法。 • 3.掌握File类及其方法的使用。 • 练习内容: • 1.将http://www.sohu.com的内容读出,并将其内容保存到sohu.txt文件中。 • 2.分别列出本机C盘下文件和文件夹的名字。对于文件,同时列出其他详细信息。 • 3.在D盘下建立文件a.txt并对其进行编辑,然后建立文件b.txt,将a.txt的内容拷贝到b.txt中。