作者:gqk
1.1、本次预计讲解的知识点
1、 掌握 File 类的使用,并可以使用 File 类进行文件本身的操作;
2、 掌握字节流和字符流的使用,并掌握 IO 操作的基本原理;
3、 掌握打印流、文件操作流、内存操作流的使用 4、 掌握对象序列化的使用。
IO 操作作为整个 JAVA 中最复杂的开发包,将作为一个难点出现,但是要想跨过此部分,就必须对面向对象的基本 概念非常的熟悉,对于抽象类也要熟悉。 根据实例化子类的不同,完成的功能也不同。这句话就是 IO 操作的核心。 整个 IO 包中实际上需要的就是五个类和一个接口:File、OutputStream、InputStream、Writer、Reader;Serializable。
所有的类和接口基本上都在 java.io包中定义的。2.1、File 类(重点)
File 类在整个 IO 包中是唯一一个与文件本身有关的操作类,所谓的与文件本身有关指的是创建、删除文件等操作。 在 java.io包中的 File类本身是一个跨平台的文件操作类,所以在操作中要更多的考虑到各个操作系统的区别。
File类的构造:public File(String pathname),在建立 File对象的时候需要指定一个路径。
现在要想创建一个文件,可以使用方法:public boolean createNewFile() throws IOException
package com.xkrj.gqk;import java.io.File;import java.io.IOException;public class Demo { public static void main(String[] args) throws IOException { File file = new File("d:\\temp.txt"); // 指定要操作的文件路径 file.createNewFile(); }}
既然可以创建文件,那肯定也可以删除:public boolean delete() 但是如果要想删除文件,则肯定要判断文件是否存在:public boolean exists() 那么下面完成这样的一个程序:如果文件存在,则删除掉,如果文件不存在,则创建新的。
package com.xkrj.gqk;import java.io.File;import java.io.IOException;public class Demo { public static void main(String[] args) throws IOException { File file = new File("d:\\temp.txt"); // 指定要操作的文件路径 if(file.exists()){//如果文件存在 file.delete(); }else{ file.createNewFile();//创建新的文件 } }}
而且本程序也有问题,在 Java 的最大特点是可移植性,但是在不同的操作系统中路径的分 割符肯定是不一样的:
· windows 中使用“\”
· linux中使用“/”
那么要想解决这样的问题,就必须观察 File 类定义的常量:public static final String separator。
separator 是一个常量,按照常量的命名要求肯定全部的字母都要大写:SEPARATOR。这些都是由于 Java 发展的历史 原因所造成的问题。
File file = new File("d:" + File.separator + "temp.txt"); // 指定要操作的文件路径
由于在给定文件的路径上有可能给出的是一个文件,也有可能给出的是一个文件夹,那么为了判断,在 File 类中提 供了以下的两个方法: ·
判断是否是文件: public boolean isFile() · 判断是否是文件夹: public boolean isDirectory()package com.xkrj.gqk;import java.io.File;import java.io.IOException;public class Demo { public static void main(String[] args) throws IOException { File file1 = new File("d:" + File.separator + "temp.txt"); // 指定要操作的文件路径 File file2 = new File("d:" + File.separator + "testjava"); // 指定要操作的文件路径 System.out.println(file1.isFile()); System.out.println(file2.isDirectory()); }}
在 File类的操作中可以通过代码列出一个文件夹之中的完整内容,方法如下: ·
列 出内容:public String[] list() 列 出内容:public File[] listFiles()实例:list()
package com.xkrj.gqk;import java.io.File;import java.io.IOException;public class Demo { public static void main(String[] args) throws IOException { File file = new File("d:" + File.separator + "Users"); // 指定要操作的文件路径 if(file.isDirectory()){//如果是一个文件 String[] list = file.list();//列出全部内容 for(String str : list){ System.out.println(str); } }else{ System.out.println(file.getName()); } }}
实例:listFiles()
package com.xkrj.gqk;import java.io.File;import java.io.IOException;public class Demo { public static void main(String[] args) throws IOException { File file = new File("d:" + File.separator + "Users"); // 指定要操作的文件路径 if(file.isDirectory()){//如果是一个文件 File[] list = file.listFiles();//列出全部内容 for(File str : list){ System.out.println(str);//输出的是全路径File对象 } }else{ System.out.println(file.getName()); } }}
发现使用 listFiles()方法输出的时候可以输出一个完整的路径,而且返回的是 File 类的对象,可以进行更多的操作。(比如说文件的长度)
思考题:
现在要求输出一个给定目录中的全部文件的路径。
本程序肯定只能依靠递归的操作完成,因为在一个给定的路径下有可能还是文件夹,那么如果是文件夹的话则肯定 要继续列出,重复判断。
package com.xkrj.gqk;import java.io.File;import java.io.IOException;public class Demo { public static void main(String[] args) throws IOException { File file = new File("d:" + File.separator); // 指定要操作的文件路径 list(file); } public static void list(File file){ if(file.isDirectory()){//如果是文件 File[] files = file.listFiles();//列出全部文件 if(files!=null){//如果文件存在 for(int i = 0;i
3.1、字节流与字符流(核心重点)
File类本身是与文件操作有关,但是如果要想操作内容则必须使用字节流或字符流完成,但是不管是使用何种的输入 输出流,其基本的操作原理是一样的(以文件流为准)
1 、使用 File 类找到一个文件
2 、通过字节流或字符流的子类进行对象的实例化3 、 进行读或写的操作
4 、关 闭 字 节 或 字符流由于流的操作属于资源操作,所以在操作的最后一定要关闭以释放资源.
操作流有以下几个:
字 节流:OutputStream、InputStream字符流:Writer,Reader
3.2.1、字节输出流
字节输出流使用的是 OutputStream,此类定义如下:
public abstract class OutputStream extends Object implements Closeable, Flushable
本类是一个抽象类,根据面向对象的概念,要通过子类进行对象的实例化操作。
在此类中定义了如下的几个常用方法:
关 闭 流 : public void close() throws IOException
写 一 组 数据:public void write(byte[] b) throws IOException
写一个数据:public void write(int b) throws IOException
但是要想为 OutputStream 实例化,且进行文件操作的话,就要使用 FileOutputStream 子类。
FileOutputStream的构造:public FileOutputStream(File file) throws FileNotFoundException
范例:使用字节流进行输出,输出“Hello World”。
package com.xkrj.gqk;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;public class Demo { public static void main(String[] args) throws IOException { File file = new File("d:" + File.separator+"temp.txt"); // 指定要操作的文件路径 // 2、实例化OutputStream对象 OutputStream out = new FileOutputStream(file); String str = "HelloWorld"; byte[] b = new byte[1024]; b = str.getBytes(); out.write(b); out.close(); }}
现在已经可以向文件中输出内容了,但是此时程序每执行一次,实际上都会输出,但是属于覆盖的操作,
像文件中追加内容:
public FileOutputStream(File file, boolean append) throws FileNotFoundException
创建一个向指定 File
对象表示的文件中写入数据的文件输出流。如果第二个参数为 true
,则将字节写入文件末尾处,而不是写入文件开始处。创建一个新 FileDescriptor
对象来表示此文件连接。
package com.xkrj.gqk;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;public class Demo { public static void main(String[] args) throws IOException { File file = new File("d:" + File.separator+"temp.txt"); // 指定要操作的文件路径 // 2、实例化OutputStream对象 OutputStream out = new FileOutputStream(file,true);//文件末尾添加 String str = "\r\nHelloWorld";//换行输出 byte[] b = new byte[1024]; b = str.getBytes(); out.write(b); out.close(); }}
3.2.2、字节输入流
在 InputStream 类中也可以每次读取一个字节。
3.2.3、字符输出流
Writer 属于字符输出流,Writer 类也是一个抽象类,既然要操作文件,肯定使用 FileWriter。
3.2.4、字符输入流
Reader 也肯定是一个抽象类,要输入文件使用 FileReader
3.2.5、字节流和字符流的区别
以证明字符流确实使用了缓冲区: ·
字 节流:程序 文件 · 字符流:程序 缓冲区 文件两者相比,肯定使用字节流更加的方便,而且在程序中像图片、MP3 等都是采用字节的方式的保存,那么肯定字节 流会比字符流使用的更广泛。
但是需要说明的是,如果要是想操作中文的话,字符流肯定是最好使的。
3.2.6、思考题
现在要求完成一个 Copy程序,完全模仿 DOS 中的拷贝命令
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class Demo { public static void main(String[] args) throws IOException { if (args.length != 2) { System.out.println("语法命令不正确!"); System.exit(1); } File file1 = new File(args[0]); if (file1.exists()) { // 如果源文件存在 File file2 = new File(args[1]); InputStream input = new FileInputStream(file1); OutputStream output = new FileOutputStream(file2); int temp = 0; while ((temp = input.read()) != -1) { // 边读边写 output.write(temp); // 输出 } input.close(); output.close(); System.out.println("文件拷贝完成。"); } }}