java项目中的文件目录怎么写(【每日一学】文件操作终极指南:Java开发者不可错过的技能)java基础 / Java文件与目录操作...

wufei123 发布于 2024-06-19 阅读(6)

学习总目标

本次学习目标

1 java.io.File类1.1 概述File类是java.io包下代表与平台无关的文件和目录,也就是说如果希望在程序中操作文件和目录都可以通过File类来完成,File类能新建、删除、重命名文件和目录。

在API中File的解释是文件和目录路径名的抽象表示形式,即File类是文件或目录的路径,而不是文件本身,因此File类不能直接访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流File类代表磁盘或网络中某个文件或目录的路径名称,如:/atguigu/javase/io/佟刚.jpg。

但不能直接通过File对象读取和写入数据,如果要操作数据,需要IO流。File对象好比是到水库的“路线地址”,要“存取”里面的水到你“家里”,需要“管道”。

1.2 构造方法•public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 •public File(String parent, String child) :从。

父路径名字符串和子路径名字符串创建新的 File实例•public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例小贴士:1.一个File对象代表硬盘或网络中可能存在的一个文件或者目录。

2.无论该路径下是否存在文件或者目录,都不影响File对象的创建3.如果File对象代表的文件或目录存在,则File对象实例初始化时,就会用硬盘中对应文件或目录的属性信息(例如,时间、类型等)为File对象的属性赋值,否则除了路径和名称,File对象的其他属性将会保留默认值。

1.3 常用方法1、获取文件和目录基本信息的方法•public String getName() :返回由此File表示的文件或目录的名称•public long length() :返回由此File表示的文件的长度。

•public String getPath() :将此File转换为路径名字符串•public long lastModified():返回File对象对应的文件或目录的最后修改时间(毫秒值)API中说明:length(),表示文件的长度。

如果File对象表示目录,则返回值未指定2、各种路径问题•public String getPath() :将此File转换为路径名字符串•public String getAbsolutePath() :返回此File的绝对路径名字符串。

•String getCanonicalPath():返回此File对象所对应的规范路径名File类可以使用文件路径字符串来创建File实例,该文件路径字符串既可以是绝对路径,也可以是相对路径默认情况下,系统总是依据用户的工作路径来解释相对路径,这个路径由系统属性“user.dir”指定,通常也就是运行Java虚拟机时所作的路径。

•绝对路径:从盘符开始的路径,这是一个完整的路径•相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用•规范路径:所谓规范路径名,即对路径中的“..”等进行解析后的路径名package com

.atguigu.file;importorg.junit.Test;importjava.io.File;importjava.io.IOException;publicclass FilePath

{@Testpublicvoidtest1()throwsIOException{File f1 =newFile("d:\\atguigu\\javase\\HelloIO.java");//绝对路径

System.out.println("文件/目录的名称:"+ f1.getName());System.out.println("文件/目录的构造路径名:"+ f1.getPath());System

.out.println("文件/目录的绝对路径名:"+ f1.getAbsolutePath());System.out.println("文件/目录的规范路径名:"+ f1.getCanonicalPath

());System.out.println("文件/目录的父目录名:"+ f1.getParent());}@Testpublicvoidtest02()throwsIOException{File f2

=newFile("/HelloIO.java");//绝对路径,从根路径开始System.out.println("文件/目录的名称:"+ f2.getName());System.out.println

("文件/目录的构造路径名:"+ f2.getPath());System.out.println("文件/目录的绝对路径名:"+ f2.getAbsolutePath());System.out.println

("文件/目录的规范路径名:"+ f2.getCanonicalPath());System.out.println("文件/目录的父目录名:"+ f2.getParent());}@Testpublic

voidtest03()throwsIOException{File f3 =newFile("HelloIO.java");//相对路径System.out.println("user.dir ="+

System.getProperty("user.dir"));System.out.println("文件/目录的名称:"+ f3.getName());System.out.println("文件/目录的构造路径名:"

+ f3.getPath());System.out.println("文件/目录的绝对路径名:"+ f3.getAbsolutePath());System.out.println("文件/目录的规范路径名:"

+ f3.getCanonicalPath());System.out.println("文件/目录的父目录名:"+ f3.getParent());}@Testpublicvoidtest04()throws

IOException{File f4 =newFile("../../HelloIO.java");//相对路径System.out.println("user.dir ="+System.getProperty

("user.dir"));System.out.println("文件/目录的名称:"+ f4.getName());System.out.println("文件/目录的构造路径名:"+ f4.getPath

());System.out.println("文件/目录的绝对路径名:"+ f4.getAbsolutePath());System.out.println("文件/目录的规范路径名:"+ f4.getCanonicalPath

());System.out.println("文件/目录的父目录名:"+ f4.getParent());}publicstaticvoidmain(String[] args)throwsIOException

{File f5 =newFile("HelloIO.java");//相对路径System.out.println("user.dir ="+System.getProperty("user.dir"

));System.out.println("文件/目录的名称:"+ f5.getName());System.out.println("文件/目录的构造路径名:"+ f5.getPath());System

.out.println("文件/目录的绝对路径名:"+ f5.getAbsolutePath());System.out.println("文件/目录的规范路径名:"+ f5.getCanonicalPath

());System.out.println("文件/目录的父目录名:"+ f5.getParent());}}•window的路径分隔符使用“”,而Java程序中的“”表示转义字符,所以在Windows中表示路径,需要用“\”。

或者直接使用“/”也可以,Java程序支持将“/”当成平台无关的路径分隔符或者直接使用File.separator常量值表示•把构造File对象指定的文件或目录的路径名,称为构造路径,它可以是绝对路径,也可以是相对路径

•当构造路径是绝对路径时,那么getPath和getAbsolutePath结果一样•当构造路径是相对路径时,那么getAbsolutePath的路径 = user.dir的路径 + 构造路径•当路径中不包含”..”和”/开头”等形式的路径,那么规范路径和绝对路径一样,否则会将..等进行解析。

路径中如果出现“..”表示上一级目录,路径名如果以“/”开头,表示从“根目录”下开始导航3、判断功能的方法•public boolean exists() :此File表示的文件或目录是否实际存在•public boolean isDirectory() :此File表示的是否为目录。

•public boolean isFile() :此File表示的是否为文件方法演示,代码如下:package com.atguigu.file;importjava.io.File;publicclass

FileIs {publicstaticvoidmain(String[] args){File f =newFile("d:\\aaa\\bbb.java");File f2 =newFile("d:\\aaa"

);// 判断是否存在System.out.println("d:\\aaa\\bbb.java 是否存在:"+f.exists());System.out.println("d:\\aaa 是否存在:"

+f2.exists());// 判断是文件还是目录System.out.println("d:\\aaa 文件?:"+f2.isFile());System.out.println("d:\\aaa 目录?:"

+f2.isDirectory());}}输出结果: d:\aaa\bbb.java 是否存在:trued:\aaa 是否存在:trued:\aaa 文件?:falsed:\aaa 目录?:true如果文件或目录不存在,那么exists()、isFile()和isDirectory()都是返回true

4、创建删除功能的方法•public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件•public boolean delete() :删除由此File表示的文件或目录。

只能删除空目录•public boolean mkdir() :创建由此File表示的目录•public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录方法演示,代码如下:

package com.atguigu.file;importjava.io.File;importjava.io.IOException;publicclass FileCreateDelete {public

staticvoidmain(String[] args)throwsIOException{// 文件的创建File f =newFile("aaa.txt");System.out.println(

"aaa.txt是否存在:"+f.exists());System.out.println("aaa.txt是否创建:"+f.createNewFile());System.out.println("aaa.txt是否存在:"

+f.exists());// 目录的创建File f2=newFile("newDir");System.out.println("newDir是否存在:"+f2.exists());System.out

.println("newDir是否创建:"+f2.mkdir());System.out.println("newDir是否存在:"+f2.exists());// 创建一级目录File f3=new

File("newDira\\newDirb");System.out.println("newDira\\newDirb创建:"+ f3.mkdir());File f4=newFile("newDir\\newDirb"

);System.out.println("newDir\\newDirb创建:"+ f4.mkdir());// 创建多级目录File f5=newFile("newDira\\newDirb");System

.out.println("newDira\\newDirb创建:"+ f5.mkdirs());// 文件的删除System.out.println("aaa.txt删除:"+ f.delete());

// 目录的删除System.out.println("newDir删除:"+ f2.delete());System.out.println("newDir\\newDirb删除:"+ f4.delete

());}}运行结果: aaa.txt是否存在:falseaaa.txt是否创建:trueaaa.txt是否存在:truenewDir是否存在:falsenewDir是否创建:truenewDir是否存在

:truenewDira\newDirb创建:false newDir\newDirb创建:true newDira\newDirb创建:true aaa.txt删除:true newDir删除:false

newDir\newDirb删除:trueAPI中说明:delete方法,如果此File表示目录,则目录必须为空才能删除5、列出目录的下一级•public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。

•public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录 •public File[] listFiles(FileFilter filter):返回所有满足指定过滤器的文件和目录。

如果给定 filter 为 null,则接受所有路径名否则,当且仅当在路径名上调用过滤器的 FileFilter.accept(File pathname)方法返回 true 时,该路径名才满足过滤器如果当前File对象不表示一个目录,或者发生 I/O 错误,则返回 null。

•public String[] list(FilenameFilter filter):返回返回所有满足指定过滤器的文件和目录如果给定 filter 为 null,则接受所有路径名否则,当且仅当在路径名上调用过滤器的 FilenameFilter .accept(File dir, String name)方法返回 true 时,该路径名才满足过滤器。

如果当前File对象不表示一个目录,或者发生 I/O 错误,则返回 null•public File[] listFiles(FilenameFilter filter):返回返回所有满足指定过滤器的文件和目录。

如果给定 filter 为 null,则接受所有路径名否则,当且仅当在路径名上调用过滤器的 FilenameFilter .accept(File dir, String name)方法返回 true 时,该路径名才满足过滤器。

如果当前File对象不表示一个目录,或者发生 I/O 错误,则返回 nullpackage com.atguigu.file;importorg.junit.Test;importjava.io.File

;importjava.io.FileFilter;importjava.io.FilenameFilter;publicclass DirListFiles {@Testpublicvoidtest01

(){File dir =newFile("d:/atguigu");String[] subs = dir.list();for(String sub : subs){System.out.println

(sub);}}@Testpublicvoidtest02(){File dir =newFile("d:/atguigu");listSubFiles(dir);}publicvoidlistSubFiles

(File dir){if(dir !=null&& dir.isDirectory()){File[] listFiles = dir.listFiles();if(listFiles !=null)

{for(File sub : listFiles){listSubFiles(sub);//递归调用}}}System.out.println(dir);}@Testpublicvoidtest03()

{File dir =newFile("D:/atguigu");listByFilenameFilter(dir);}publicvoidlistByFilenameFilter(File file)

{if(file !=null&& file.isDirectory()){File[] listFiles = file.listFiles(newFilenameFilter(){@Override

publicbooleanaccept(File dir, String name){return name.endsWith(".java")||newFile(dir,name).isDirectory

();}});if(listFiles !=null){for(File sub : listFiles){if(sub !=null&& sub.isFile()){System.out.println

(sub);}listByFilenameFilter(sub);//递归调用}}}}@Testpublicvoidtest04(){File dir =newFile("D:/atguigu");listByFileFilter

(dir);}publicvoidlistByFileFilter(File file){if(file !=null&& file.isDirectory()){File[] listFiles = file

.listFiles(newFileFilter(){@Overridepublicbooleanaccept(File pathname){return pathname.getName().endsWith

(".java")|| pathname.isDirectory();}});if(listFiles !=null){for(File sub : listFiles){if(sub !=null&&

sub.isFile()){System.out.println(sub);}listByFileFilter(sub);//递归调用}}}}}2 IO概述1、什么是IO生活中,你肯定经历过这样的场景。

当你编辑一个文本文件,忘记了ctrl+s ,可能文件就白白编辑了当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input 和输出output ,即流向内存是输入流,流出内存的输出流。

Java中I/O操作主要是指使用java.io包下的内容,进行输入、输出操作输入也叫做读取数据,输出也叫做作写出数据2、IO的分类根据数据的流向分为:输入流和输出流•输入流 :把数据从其他设备上读取到内存中的流。

–以InputStream,Reader结尾•输出流 :把数据从内存 中写出到其他设备上的流–以OutputStream、Writer结尾根据数据的类型分为:字节流和字符流•字节流 :以字节为单位,读写数据的流。

–以InputStream和OutputStream结尾•字符流 :以字符为单位,读写数据的流–以Reader和Writer结尾根据IO流的角色不同分为:节点流和处理流•节点流:可以从或向一个特定的地方(节点)读写数据。

如FileReader.•处理流:是对一个已存在的流进行连接和封装,通过所封装的流的功能调用实现数据读写如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数一个流对象经过其他流的多次包装,称为流的链接。

这种设计是装饰模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),其使用一种对客户端透明的方式来动态地扩展对象的功能,它是通过继承扩展功能的替代方案之一在现实生活中你也有很多装饰者的例子,例如:人需要各种各样的衣着,不管你穿着怎样,但是,对于你个人本质来说是不变的,充其量只是在外面加上了一些装饰,有,“遮羞的”、“保暖的”、“好看的”、“防雨的”….。

常用的节点流:•文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件进行处理的节点流•字符串 StringReader StringWriter 对字符串进行处理的节点流。

•数 组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。

•管 道 PipedInputStream、PipedOutputStream、PipedReader、PipedWriter对管道进行处理的节点流常用处理流:•缓冲流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter—增加缓冲功能,避免频繁读写硬盘。

•转换流:InputStreamReader、OutputStreamReader—实现字节流和字符流之间的转换•数据流:DataInputStream、DataOutputStream -提供读写Java基础数据类型功能。

•对象流:ObjectInputStream、ObjectOutputStream–提供直接读写Java对象功能3、4大顶级抽象父类们输入流输出流字节流字节输入流InputStream字节输出流OutputStream

字符流字符输入流Reader字符输出流Writer3 字节流3.1 一切皆为字节一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此所以,字节流可以传输任意文件数据。

在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据3.2 字节输出流【OutputStream】java.io.OutputStream抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。

它定义了字节输出流的基本共性功能方法•public void write(int b) :将指定的字节输出流虽然参数为int类型四个字节,但是只会保留一个字节的信息写出•public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。

•public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流 •public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。

•public void close() :关闭此输出流并释放与此流相关联的任何系统资源小贴士:close方法,当完成流的操作时,必须调用此方法,释放系统资源3.3 FileOutputStream类。

OutputStream有很多子类,我们从最简单的一个子类开始java.io.FileOutputStream类是文件输出流,用于将数据写出到文件•public FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件。

•public FileOutputStream(String name): 创建文件输出流以指定的名称写入文件当你创建一个流对象时,必须传入一个文件路径如果该文件不存在,会创建该文件如果有这个文件,会清空这个文件的数据。

如果传入的是一个目录,则会报IOException异常1、写出字节数据package com.atguigu.fileio;importorg.junit.Test;importjava.io.FileOutputStream

;importjava.io.IOException;publicclass FOSWrite {@Testpublicvoidtest01()throwsIOException{// 使用文件名称创建流对象

FileOutputStream fos =newFileOutputStream("fos.txt");// 写出数据 fos.write(97);// 写出第1个字节 fos.write(98);// 写出第2个字节

fos.write(99);// 写出第3个字节// 关闭资源 fos.close();/* 输出结果:abc*/}@Testpublicvoidtest02()throwsIOException{// 使用文件名称创建流对象

FileOutputStream fos =newFileOutputStream("fos.txt");// 字符串转换为字节数组byte[] b ="尚硅谷".getBytes();// 写出字节数组数据

fos.write(b);// 关闭资源 fos.close();}@Testpublicvoidtest03()throwsIOException{// 使用文件名称创建流对象FileOutputStream

fos =newFileOutputStream("fos.txt");// 字符串转换为字节数组byte[] b ="abcde".getBytes();// 写出从索引2开始,2个字节索引2是c,两个字节,也就是cd。

fos.write(b,2,2);// 关闭资源 fos.close();}}2、数据追加续写经过以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据如何保留目标文件中数据,还能继续添加新数据呢?。

•public FileOutputStream(File file, boolean append): 创建文件输出流以写入由指定的 File对象表示的文件 •public FileOutputStream(String name, boolean append): 创建文件输出流以指定的名称写入文件。

这两个构造方法,参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示清空原有数据这样创建的输出流对象,就可以指定是否追加续写了,代码使用演示:package com.atguigu

.fileio;importjava.io.FileOutputStream;importjava.io.IOException;publicclass FOSWriteAppend {publicstatic

voidmain(String[] args)throwsIOException{// 使用文件名称创建流对象FileOutputStream fos =newFileOutputStream("fos.txt",true

);// 字符串转换为字节数组byte[] b ="abcde".getBytes(); fos.write(b);// 关闭资源 fos.close();}}//这段程序如果多运行几次,每次都会在原来文件末尾追加abcde

3、写出换行•回车符\r和换行符\n :–回车符:回到一行的开头(return)–换行符:下一行(newline)•系统中的换行:–Windows系统里,每行结尾是 回车+换行 ,即\r\n;–Unix系统里,每行结尾只有 换行 ,即\n;。

–Mac系统里,每行结尾是 回车 ,即\r从 Mac OS X开始与Linux统一代码使用演示:package com.atguigu.fileio;importjava.io.FileOutputStream。

;importjava.io.IOException;publicclass FOSWriteNewLine {publicstaticvoidmain(String[] args)throwsIOException

{// 使用文件名称创建流对象FileOutputStream fos =newFileOutputStream("fos.txt");// 定义字节数组byte[] words ={97,98,99,100,101

};// 遍历数组for(int i =0; i < words.length; i++){// 写出一个字节 fos.write(words[i]);// 写出一个换行, 换行符号转成数组写出 fos

.write("\r\n".getBytes());}// 关闭资源 fos.close();}}/*输出结果: a b c d e*/3.4 字节输入流【InputStream】java.io.InputStream抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。

它定义了字节输入流的基本共性功能方法•public int read(): 从输入流读取一个字节返回读取的字节值虽然读取了一个字节,但是会自动提升为int类型如果已经到达流末尾,没有数据可读,则返回-1。

•public int read(byte[] b): 从输入流中读取一些字节数,并将它们存储到字节数组 b中 每次最多读取b.length个字节返回实际读取的字节个数如果已经到达流末尾,没有数据可读,则返回-1。

•public int read(byte[] b,int off,int len):从输入流中读取一些字节数,并将它们存储到字节数组 b中,从b[off]开始存储,每次最多读取len个字节 返回实际读取的字节个数。

如果已经到达流末尾,没有数据可读,则返回-1•public void close() :关闭此输入流并释放与此流相关联的任何系统资源小贴士:close方法,当完成流的操作时,必须调用此方法,释放系统资源。

3.5 FileInputStream类java.io.FileInputStream类是文件输入流,从文件中读取字节•FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。

•FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名当你创建一个流对象时,必须传入一个文件路径。

如果文件不存在,会抛出FileNotFoundException 如果传入的是一个目录,则会报IOException异常package com.atguigu.fileio;importorg.junit

.Test;importjava.io.FileInputStream;importjava.io.IOException;publicclass FISRead {@Testpublicvoidtest

()throwsIOException{// 使用文件名称创建流对象FileInputStream fis =newFileInputStream("read.txt");// 读取数据,返回一个字节int

read = fis.read();System.out.println((char) read); read = fis.read();System.out.println((char) read);

read = fis.read();System.out.println((char) read); read = fis.read();System.out.println((char) read);

read = fis.read();System.out.println((char) read);// 读取到末尾,返回-1 read = fis.read();System.out.println

( read);// 关闭资源 fis.close();/* 文件内容:abcde 输出结果: a b c d e -1 */}@Testpublicvoidtest02()throwsIOException

{// 使用文件名称创建流对象FileInputStream fis =newFileInputStream("read.txt");// 定义变量,保存数据int b;// 循环读取while((b

= fis.read())!=-1){System.out.println((char)b);}// 关闭资源 fis.close();}@Testpublicvoidtest03()throwsIOException

{// 使用文件名称创建流对象.FileInputStream fis =newFileInputStream("read.txt");// 文件中为abcde// 定义变量,作为有效个数int len

;// 定义字节数组,作为装字节数据的容器byte[] b =newbyte[2];// 循环读取while(( len= fis.read(b))!=-1){// 每次读取后,把数组变成字符串打印System

.out.println(newString(b));}// 关闭资源 fis.close();/* 输出结果: ab cd ed 最后错误数据`d`,是由于最后一次读取时,只读取一个字节`e`,数组中,上次读取的数据没有被完全替换,所以要通过`len` ,获取有效的字节

*/}@Testpublicvoidtest04()throwsIOException{// 使用文件名称创建流对象.FileInputStream fis =newFileInputStream("read.txt"

);// 文件中为abcde// 定义变量,作为有效个数int len;// 定义字节数组,作为装字节数据的容器byte[] b =newbyte[2];// 循环读取while(( len= fis.

read(b))!=-1){// 每次读取后,把数组的有效字节部分,变成字符串打印System.out.println(newString(b,0,len));// len 每次读取的有效字节个数}// 关闭资源

fis.close();/* 输出结果: ab cd e */}}3.6 复制文件

复制图片文件,代码使用演示:package com.atguigu.fileio;importjava.io.FileInputStream;importjava.io.FileOutputStream

;importjava.io.IOException;publicclass FileCopy {publicstaticvoidmain(String[] args)throwsIOException

{// 1.创建流对象// 1.1 指定数据源FileInputStream fis =newFileInputStream("D:\\test.jpg");// 1.2 指定目的地FileOutputStream

fos =newFileOutputStream("test_copy.jpg");// 2.读写数据// 2.1 定义数组byte[] b =newbyte[1024];// 2.2 定义长度int

len;// 2.3 循环读取while((len = fis.read(b))!=-1){// 2.4 写出数据 fos.write(b, 0 , len);}// 3.关闭资源 fos.close

(); fis.close();}}4 字符流当使用字节流读取文本文件时,可能会有一个小问题就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。

小贴士:字符流,只能操作文本文件,不能操作图片,视频等非文本文件当我们单纯读或者写文本文件时 使用字符流 其他情况使用字节流4.1 字符输入流【Reader】java.io.Reader抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。

它定义了字符输入流的基本共性功能方法•public int read(): 从输入流读取一个字符 虽然读取了一个字符,但是会自动提升为int类型返回该字符的Unicode编码值如果已经到达流末尾了,则返回-1。

•public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 每次最多读取cbuf.length个字符返回实际读取的字符个数如果已经到达流末尾,没有数据可读,则返回-1。

•public int read(char[] cbuf,int off,int len):从输入流中读取一些字符,并将它们存储到字符数组 cbuf中,从cbuf[off]开始的位置存储每次最多读取len个字符。

返回实际读取的字符个数如果已经到达流末尾,没有数据可读,则返回-1•public void close() :关闭此流并释放与此流相关联的任何系统资源小贴士:close方法,当完成流的操作时,必须调用此方法,释放系统资源。

4.2 FileReader类java.io.FileReader类是读取字符文件的便利类构造时使用系统默认的字符编码和默认字节缓冲区•FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。

•FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的名称当你创建一个流对象时,必须传入一个文件路径类似于FileInputStream 。

如果该文件不存在,则报FileNotFoundException如果传入的是一个目录,则会报IOException异常package com.atguigu.fileio;importorg.junit

.Test;importjava.io.FileReader;importjava.io.IOException;publicclass FRRead {@Testpublicvoidtest01()throws

IOException{// 使用文件名称创建流对象FileReader fr =newFileReader("read.txt");// 定义变量,保存数据int b;// 循环读取while((b

= fr.read())!=-1){System.out.println((char)b);}// 关闭资源 fr.close();/*输出结果: 尚 硅 谷*/}@Testpublicvoidtest02

()throwsIOException{// 使用文件名称创建流对象FileReader fr =newFileReader("read.txt");// 定义变量,保存有效字符个数int len;// 定义字符数组,作为装字符数据的容器

char[] cbuf =newchar[2];// 循环读取while((len = fr.read(cbuf))!=-1){System.out.println(newString(cbuf));}

// 关闭资源 fr.close();/* 输出结果: 尚硅 谷硅 最后错误数据硅,是因为最后一次流中只有一个字符“谷”,读取一个字符没有覆盖char[]数组cbuf的所有元素 */}@Testpublic

voidtest03()throwsIOException{// 使用文件名称创建流对象FileReader fr =newFileReader("read.txt");// 定义变量,保存有效字符个数

int len;// 定义字符数组,作为装字符数据的容器char[] cbuf =newchar[2];// 循环读取while((len = fr.read(cbuf))!=-1){System.out

.println(newString(cbuf, 0, len));}// 关闭资源 fr.close();/* 输出结果: 尚硅 谷 */}}4.3 字符输出流【Writer】java.io.Writer抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。

它定义了字节输出流的基本共性功能方法•public void write(int c) 写入单个字符•public void write(char[] cbuf)写入字符数组•public void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。

•public void write(String str)写入字符串•public void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。

•public void flush()刷新该流的缓冲 •public void close() 关闭此流,但要先刷新它4.4 FileWriter类java.io.FileWriter类是写出字符到文件的便利类。

构造时使用系统默认的字符编码和默认字节缓冲区•FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象 •FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。

当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream如果文件不存在,则会自动创建如果文件已经存在,则会清空文件内容,写入新的内容1、写出字符数据package com.atguigu

.fileio;importorg.junit.Test;importjava.io.FileWriter;importjava.io.IOException;publicclass FWWrite {

@Testpublicvoidtest01()throwsIOException{// 使用文件名称创建流对象FileWriter fw =newFileWriter("fw.txt");// 写出数据

fw.write(97);// 写出第1个字符 fw.write(b);// 写出第2个字符 fw.write(C);// 写出第3个字符 fw.write(30000);// 写出第4个字符,中文编码表中30000对应一个汉字。

/* 【注意】FileWriter与FileOutputStream不同 如果不关闭,数据只是保存到缓冲区,并未保存到文件 */// fw.close();}@Testpublicvoidtest02()

throwsIOException{// 使用文件名称创建流对象FileWriter fw =newFileWriter("fw.txt");// 字符串转换为字节数组char[] chars ="尚硅谷"

.toCharArray();// 写出字符数组 fw.write(chars);// 尚硅谷// 写出从索引1开始,2个字符 fw.write(chars,1,2);// 硅谷// 关闭资源 fw.close

();}@Testpublicvoidtest03()throwsIOException{// 使用文件名称创建流对象FileWriter fw =newFileWriter("fw.txt");// 字符串

String msg ="尚硅谷";// 写出字符数组 fw.write(msg);//尚硅谷// 写出从索引1开始,2个字符 fw.write(msg,1,2);// 硅谷// 关闭资源 fw.close。

();}}2、续写•public FileWriter(File file,boolean append): 创建文件输出流以写入由指定的 File对象表示的文件 •public FileWriter(String fileName,boolean append): 创建文件输出流以指定的名称写入文件。

这两个构造方法,参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示清空原有数据这样创建的输出流对象,就可以指定是否追加续写了,代码使用演示:操作类似于FileOutputStream。

package com.atguigu.fileio;importorg.junit.Test;importjava.io.FileWriter;importjava.io.IOException;public

class FWWriteAppend {@Testpublicvoidtest01()throwsIOException{// 使用文件名称创建流对象,可以续写数据FileWriter fw =new

FileWriter("fw.txt",true);// 写出字符串 fw.write("尚硅谷真棒");// 关闭资源 fw.close();}}3、换行package com.atguigu.fileio

;importjava.io.FileWriter;importjava.io.IOException;publicclass FWWriteNewLine {publicstaticvoidmain(

String[] args)throwsIOException{// 使用文件名称创建流对象,可以续写数据FileWriter fw =newFileWriter("fw.txt");// 写出字符串 fw

.write("尚");// 写出换行 fw.write("\r\n");// 写出字符串 fw.write("硅谷");// 关闭资源 fw.close();}}4、关闭和刷新【注意】FileWriter与FileOutputStream不同。

因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中但是关闭的流对象,是无法继续写出数据的如果我们既想写出数据,又想继续使用流,就需要flush 方法了•flush :刷新缓冲区,流对象可以继续使用。

•close:先刷新缓冲区,然后通知系统释放资源流对象不可以再被使用了代码使用演示:package com.atguigu.fileio;importjava.io.FileWriter;importjava

.io.IOException;publicclass FWWriteFlush {publicstaticvoidmain(String[] args)throwsIOException{// 使用文件名称创建流对象

FileWriter fw =newFileWriter("fw.txt");// 写出数据,通过flush fw.write(刷);// 写出第1个字符 fw.flush(); fw.write(新);

// 继续写出第2个字符,写出成功 fw.flush();// 写出数据,通过close fw.write(关);// 写出第1个字符 fw.close(); fw.write(闭);// 继续写出第2个字符,【报错】java.io.IOException: Stream closed

fw.close();}}小贴士:即便是flush方法写出了数据,操作的最后还是要调用close方法,释放系统资源5 缓冲流缓冲流,也叫高效流,按照数据类型分类:•字节缓冲流:BufferedInputStream,BufferedOutputStream。

•字符缓冲流:BufferedReader,BufferedWriter缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率5.1 构造方法

•public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流•public BufferedOutputStream(OutputStream out): 创建一个新的缓冲输出流。

构造举例,代码如下:// 创建字节缓冲输入流BufferedInputStream bis =newBufferedInputStream(newFileInputStream("bis.txt"));

// 创建字节缓冲输出流BufferedOutputStream bos =newBufferedOutputStream(newFileOutputStream("bos.txt"));•public BufferedReader(Reader in) :创建一个 新的缓冲输入流。

•public BufferedWriter(Writer out): 创建一个新的缓冲输出流构造举例,代码如下:// 创建字符缓冲输入流BufferedReader br =newBufferedReader。

(newFileReader("br.txt"));// 创建字符缓冲输出流BufferedWriter bw =newBufferedWriter(newFileWriter("bw.txt"));5.2 效率测试

查询API,缓冲流读写方法与基本的流是一致的,我们通过复制大文件(375MB),测试它的效率package com.atguigu.buffer;importorg.junit.Test;importjava

.io.*;publicclass BufferedIO {@TestpublicvoidtestNoBuffer()throwsIOException{// 记录开始时间long start =System

.currentTimeMillis();// 创建流对象FileInputStream fis =newFileInputStream("jdk8.exe");FileOutputStream fos

=newFileOutputStream("copy.exe");// 读写数据byte[] data =newbyte[1024];int len;while((len = fis.read(data

))!=-1){ fos.write(data,0,len);} fos.close(); fis.close();// 记录结束时间long end =System.currentTimeMillis

();System.out.println("普通流复制时间:"+(end - start)+" 毫秒");}@TestpublicvoidtestUseBuffer()throwsIOException

{// 记录开始时间long start =System.currentTimeMillis();// 创建流对象BufferedInputStream bis =newBufferedInputStream

(newFileInputStream("jdk8.exe"));BufferedOutputStream bos =newBufferedOutputStream(newFileOutputStream

("copy.exe"));// 读写数据int len;byte[] data =newbyte[1024];while((len = bis.read(data))!=-1){ bos.write(

data, 0 , len);} bos.close(); bis.close();// 记录结束时间long end =System.currentTimeMillis();System.out.println

("缓冲流使用数组复制时间:"+(end - start)+" 毫秒");}}5.3 字符缓冲流特有方法字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法•BufferedReader:public String readLine(): 读一行文字。

•BufferedWriter:public void newLine(): 写一行行分隔符,由系统属性定义符号package com.atguigu.buffer;importorg.junit.Test

;importjava.io.*;publicclass BufferedIOLine {@TestpublicvoidtestReadLine()throwsIOException{// 创建流对象BufferedReader

br =newBufferedReader(newFileReader("in.txt"));// 定义字符串,保存读取的一行文字String line;// 循环读取,读取到最后返回nullwhile

((line = br.readLine())!=null){System.out.println(line);}// 释放资源 br.close();}@TestpublicvoidtestNewLine

()throwsIOException{// 创建流对象BufferedWriter bw =newBufferedWriter(newFileWriter("out.txt"));// 写出数据 bw

.write("尚");// 写出换行 bw.newLine(); bw.write("硅"); bw.newLine(); bw.write("谷"); bw.newLine();// 释放资源 bw

.close();}}5.4 流的关闭顺序package com.atguigu.buffer;importorg.junit.Test;importjava.io.BufferedWriter;import

java.io.FileWriter;importjava.io.IOException;publicclass IOClose {@Testpublicvoidtest01()throwsIOException

{FileWriter fw =newFileWriter("d:/1.txt");BufferedWriter bw =newBufferedWriter(fw); bw.write("hello");

fw.close(); bw.close();//java.io.IOException: Stream closed/* 缓冲流BufferedWriter,把数据先写到缓冲区, 默认情况下是当缓冲区满,或调用close,或调用flush这些情况才会把缓冲区的数据输出。

bw.close()时,需要把数据从缓冲区的数据输出 数据的流向: 写到bw(缓冲区)-->fw ->"d:/1.txt" 此时,我先把fw关闭了,bw的数据无法输出了 */}@Testpublicvoid

test02()throwsIOException{FileWriter fw =newFileWriter("d:/1.txt");BufferedWriter bw =newBufferedWriter

(fw); bw.write("hello"); bw.close(); fw.close();/* 原则: 先关外面的,再关里面的 例如: FileWriter fw = new FileWriter("d:/1.txt"); //里面 穿内衣。

BufferedWriter bw = new BufferedWriter(fw); //外面 穿外套 关闭 bw.close(); //先关外面的 先脱外套 fw.close(); //再关里面的 再脱内衣

*/}}

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

河南中青旅行社综合资讯 奇遇综合资讯 盛世蓟州综合资讯 综合资讯 游戏百科综合资讯 新闻155