网站建设计划方案模板下载,七牛 wordpress 节省空间,asp源码-漂亮企业源码大气公司网站模版,淘宝推广怎么推IO操作主要是指使用Java程序完成输入#xff08;Input#xff09;、输出#xff08;Output#xff09;操作。所谓输入是指将文件内容以数据流的形式读取到内存中#xff0c;输出是指通过Java程序将内存中的数据写入到文件中#xff0c;输入、输出操作在实际开发中应用较为…IO操作主要是指使用Java程序完成输入Input、输出Output操作。所谓输入是指将文件内容以数据流的形式读取到内存中输出是指通过Java程序将内存中的数据写入到文件中输入、输出操作在实际开发中应用较为广泛。本章将针对IO的相关操作进行讲解。
1. File类
1.1. File类的构造方法
File类提供了多个构造方法用于创建File对象具体如下表所示。 方法声明 功能描述 File(String pathname) 通过指定的一个字符串类型的文件路径来创建一个新的File对象 File(String parent,String child) 根据指定的一个字符串类型的父路径和一个字符串类型的子路径包括文件名称创建一个File对象 File(File parent,String child) 根据指定的File类的父路径和字符串类型的子路径包括文件名称创建一个File对象
下面通过一个案例演示如何使用File类的构造方法创建File对象。具体代码如下所示。
Test
public void test1(){File f1 new File(D:\\file\\hello.txt); //使用绝对路径创建File对象File f2 new File(src\\Hello.java); //使用相对路径创建File对象System.out.println(f1);System.out.println(f2);
}
注意案例在创建File对象时传入的路径使用了\\这是因为Windows中的目录符号为反斜线\但反斜线\在Java中是特殊字符具有转义作用所以使用反斜线\时前面应该再添加一个反斜线即为\\。此外目录符号还可以用正斜线/表示如“D:/file/hello.txt”。
1.2. File类的常用方法
File类提供了一系列方法例如判断文件是否存在、获取文件的名称、文件的大小、文件的路径、删除文件等用于操作File类对象内部封装的路径指向的文件或者目录。具体如下表所示。 方法声明 功能描述 boolean exists() 判断File对象对应的文件或目录是否存在若存在则返回true否则返回false boolean delete() 删除File对象对应的文件或目录若删除成功则返回true否则返回false boolean createNewFile() 当File对象对应的文件不存在时该方法将新建一个文件若创建成功则返回true否则返回false String getName() 返回File对象表示的文件或文件夹的名称 String getPath() 返回File对象对应的路径 String getAbsolutePath() 返回File对象对应的绝对路径(在Unix/Linux等系统上如果路径是以正斜线/开始则这个路径是绝对路径在Windows等系统上如果路径是从盘符开始则这个路径是绝对路径) String getParentFile() 返回File对象对应目录的父目录(即返回的目录不包含最后一级子目录) boolean canRead() 判断File对象对应的文件或目录是否可读若可读则返回true反之返回false boolean canWrite() 判断File对象对应的文件或目录是否可写若可写则返回true反之返回false boolean isFile() 判断File对象对应的是否是文件(不是目录)若是文件则返回true反之返回false boolean isDirectory() 判断File对象对应的是否是目录(不是文件)若是目录则返回true反之返回false boolean isAbsolute() 判断File对象对应的文件或目录是否是绝对路径 long lastModified() 返回1970年1月1日0时0分0秒到文件最后修改时间的毫秒值 long length() 返回文件内容的长度单位是字节 String[] list() 递归列出指定目录的全部内容包括子目录与文件只是列出名称 File[] listFiles() 返回一个包含了File对象所有子文件和子目录的File数组
下面通过一个案例演示如何使用File类的常用方法。具体代码如下所示。
Test
public void test2() {File file new File(src/Hello.java);System.out.println(文件是否存在 file.exists());System.out.println(文件名 file.getName());System.out.println(文件大小 file.length() bytes);System.out.println(文件相对路径 file.getPath());System.out.println(文件绝对路径 file.getAbsolutePath());System.out.println(文件是否为文件 file.isFile());System.out.println(文件删除是否成功 file.delete());
}
1.3. 遍历目录下的文件
通过调用File类中的list()方法可以遍历目录下的文件。按照调用方法的不同目录下的文件遍历可分为以下3种方式。 遍历指定目录下的所有文件。
Test
public void test3(){// 创建File对象File file new File(D:\\workspace-java\\case05);if (file.isDirectory()) { // 判断File对象对应的目录是否存在String[] names file.list (); // 获得目录下的所有文件的文件名for (String name : names) {System.out.println(name); // 输出文件名}}
} 遍历指定目录下指定扩展名的文件。
有时程序需要获取指定类型的文件如获取指定目录下所有的“.java”文件。针对这种需求File类提供了一个重载的list()方法该方法接收一个FilenameFilter类型的参数。FilenameFilter是一个接口被称作文件过滤器其中定义了一个抽象方法accept()用于依次对指定File的所有子目录或文件进行迭代。在调用list()方法时需要实现文件过滤器FilenameFilter并在accept()方法中进行筛选从而获得指定类型的文件。
Test
public void test4() {// 创建File对象File file new File(D:\\workspace-java\\case05\\src\\com\\wfit\\test01);// 创建过滤器对象FilenameFilter filter new FilenameFilter() {// 实现accept()方法public boolean accept(File dir, String name) {File currFile new File(dir, name);// 如果文件名以.java结尾返回true否则返回falseif (currFile.isFile() name.endsWith(.java)) {return true;} else {return false;}}};if (file.exists()) { // 判断File对象对应的目录是否存在String[] lists file.list(filter); // 获得过滤后的所有文件名数组for (String name : lists) {System.out.println(name);}}
} 遍历包括子目录中的文件在内的所有文件。
有时候在一个目录下除了文件还有子目录如果想获取所有子目录下的文件list()方法显然不能满足要求这时可以使用File类提供的另一个方法listFiles()。listFiles()方法返回一个File对象数组当对数组中的元素进行遍历时如果元素中还有子目录需要遍历则可以使用递归再次遍历子目录。
Test
public void test5() {// 创建一个代表目录的File对象File file new File(D:\\workspace-java\\case05\\src\\com\\wfit);fileDir(file); // 调用FileDir方法
}
public void fileDir(File dir) {File[] files dir.listFiles(); // 获得表示目录下所有文件的数组for (File file : files) { // 遍历所有的子目录和文件if (file.isDirectory()) {fileDir(file); // 如果是目录递归调用fileDir()}System.out.println(file.getAbsolutePath()); // 输出文件的绝对路径}
}
1.4. 删除文件及目录
在操作文件时可能会遇到需要删除一个目录下的某个文件或者删除整个目录的情况这时可以调用File类的delete()方法。
Test
public void test6(){File file new File(D:\\test\\testdel);deleteDir(file); // 调用deleteDir删除方法System.out.println(删除成功!);
}
public void deleteDir(File dir) {if (dir.exists()) { // 判断传入的File对象是否存在File[] files dir.listFiles(); // 得到File数组for (File file : files) { // 遍历所有的子目录和文件if (file.isDirectory()) {deleteDir(file); // 如果是目录递归调用deleteDir()} else {file.delete(); // 如果是文件直接删除}}// 删除完一个目录里的所有文件后就删除这个目录dir.delete();}
}
2. 字节流
在程序的开发中经常需要处理设备之间的数据传输而计算机中无论是文本、图片、音频还是视频所有文件都是以二进制字节形式存在的。对于字节的输入输出I/O流提供了一系列的流统称为字节流字节流是程序中最常用的流根据数据的传输方向可将其分为字节输入流和字节输出流。
JDK提供了两个抽象类InputStream和OutputStream它们是字节流的顶级父类所有的字节输入流都继承自InputStream所有的字节输出流都继承自OutputStream。为了方便理解可以把InputStream和OutputStream比作两根“水管”具体如下 在上图中InputStream被看成一个输入管道OutputStream被看成一个输出管道数据通过InputStream从源设备输入到程序通过OutputStream从程序输出到目标设备从而实现数据的传输。由此可见I/O流中的输入输出都是相对于程序而言的。
2.1. InputStream类 InputStream类的常用方法
InputStream类提供了一系列与读数据相关的方法。具体如下表所示。 方法声明 功能描述 int read() 从输入流读取一个8位的字节把它转换为0~255之间的整数并返回这一整数 int read(byte[] b) 从输入流读取若干字节把它们保存到参数b指定的字节数组中返回的整数表示读取字节的数目 int read(byte[] b,int off,int len) 从输入流读取若干字节把它们保存到参数b指定的字节数组中off指定字节数组开始保存数据的起始索引len表示读取的字节数目 void close() 关闭此输入流并释放与该流关联的所有系统资源 InputStream体系结构
InputStream类虽然提供了一系列和读数据有关的方法但是InputStream类是抽象类不能被实例化因此针对不同的功能InputStream类提供了不同的子类这些子类形成了一个体系结构。如下图所示。 字节流FileInputStream
InputStream就是JDK提供的基本输入流它是所有输入流的父类FileInputStream是InputStream的子类它是操作文件的字节输入流专门用于读取文件中的数据。
Test
public void test1(){File file new File(d:\\filetest\\hello.txt);//从文件中读取数据try{FileInputStream in new FileInputStream(file);int len in.read();while(len ! -1){System.out.print((char)len);len in.read();}in.close();}catch (Exception e){System.out.println(e.toString());}
}
2.2. OutputStream类 OutputStream类的常用方法
OutputStream类提供了一系列与写数据相关的方法。具体如下表所示。 方法声明 功能描述 void write(int b) 向输出流写入一个字节 void write(byte[] b) 把参数b指定的字节数组的所有字节写到输出流 void write(byte[] b,int off,int len) 将指定byte数组中从偏移量off开始的len个字节写入输出流 void flush() 刷新此输出流并强制写出所有缓冲的输出字节 void close() 关闭此输出流并释放与此流相关的所有系统资源 OutputStream体系结构
OutputStream类虽然提供了一系列和写数据有关的方法但是OutputStream类是抽象类不能被实例化因此针对不同的功能OutputStream类提供了不同的子类这些子类形成了一个体系结构。如下图所示。 字节流FileOutputStream
OutputStream是JDK提供的最基本的输出流与InputStream类似OutputStream也是抽象类它是所有输出流的父类。OutputStream是一个抽象类如果使用此类则必须先通过子类实例化对象。OutputStream类有多个子类其中FileOutputStream子类是操作文件的字节输出流专门用于把数据写入文件。
Test
public void test2(){File file new File(d:\\filetest\\hello.txt);//向文件中写入数据FileOutputStream out null;try{out new FileOutputStream(file);String str hello wfit;out.write(str.getBytes());out.close();}catch (Exception e){System.out.println(e.toString());}
}
2.3. 文件的复制
在应用程序中I/O流通常都是成对出现的即输入流和输出流一起使用。例如文件的复制就需要通过输入流读取文件中的数据再通过输出流将数据写入文件。
编写程序使用FileInputStream和FileOutputStream将文件helloA.txt 的内容复制到helloB.txt文件中。
Test
public void test3(){File helloA new File(d:\\filetest\\helloA.txt);File helloB new File(d:\\filetest\\helloB.txt);try{FileInputStream in new FileInputStream(helloA);FileOutputStream out new FileOutputStream(helloB);int len in.read();while(len ! -1){out.write(len);len in.read();}in.close();out.close();}catch (Exception e){System.out.println(e.toString());}
}
3. 字符流
前面讲解内容都是通过字节流直接对文件进行读写如果读写的文件内容是字符考虑到使用字节流读写字符可能存在传输效率以及数据编码问题此时建议使用字符流。同字节流一样字符流也有两个抽象的顶级父类分别是Reader类和Writer类。其中Reader类是字符输入流用于从某个源设备读取字符。Writer类是字符输出流用于向某个目标设备写入字符。
3.1. Reader类 Reader类的常用方法
Reader类提供了一系列与读数据相关的方法。具体如下表所示。 方法声明 功能描述 int read() 以字符为单位读数据 int read(char cbuf[]) 将数据读入char类型数组并返回数据长度 int read(char cbuf[],int off,int len) 将数据读入char类型数组的指定区间并返回数据长度 void close() 关闭数据流 long transferTo(Writer out) 将数据直接读入字符输出流 Reader体系结构
Reader类作为字符流的顶级父类也有许多子类下面通过一张继承关系图列举Reader类的常用子类。如下图所示。 字符流FileReader
在程序开发中经常需要对文本文件的内容进行读取如果想从文件中直接读取字符便可以使用字符输入流FileReader通过此流可以从关联的文件中读取一个或一组字符。
编写程序使用FileReader对象从hello.txt文件中读出字符并输出。
Test
public void test1(){File file new File(d:\\filetest\\hello.txt);try{FileReader in new FileReader(file);BufferedReader ins new BufferedReader(in);String line;while ((line ins.readLine()) ! null){System.out.println(line);}ins.close();in.close();}catch (Exception e){System.out.println(e.toString());}
}
3.2. Writer类 Writer类的常用方法
Writer类提供了一系列与写数据相关的方法。具体如下表所示。 方法声明 功能描述 void write(int c) 以字符为单位写数据 void write(char cbuf[]) 将char类型数组中的数据写出 void write(char cbuf[],int off,int len) 将char类型数组中指定区间的数据写出 void write(String str) 将String类型的数据写出 void wirte(String str,int off,int len) 将String类型指定区间的数据写出 void flush() 可以强制将缓冲区的数据同步到输出流中 void close() 关闭数据流 Writer体系结构
Writer类作为字符流的顶级父类也有许多子类下面通过一张继承关系图列举Writer类的常用子类。如下图所示。 字符流FileWriter
在程序开发中有时需要向文本文件写入内容通过字符流向文本文件写入内容需要使用FileWriter类FileWriter类可以一次向文件中写入一个或一组字符。
下面通过一个案例学习如何使用FileWriter字符流将字符写入文件。具体代码如下所示。
Test
public void test2(){File file new File(d:\\filetest\\hello.txt);try{FileWriter out new FileWriter(file);String str hello wfit;out.write(str);out.close();}catch (Exception e){System.out.println(e.toString());}
}
4. 转换流
I/O流分为字节流和字符流字节流和字符流之间可以进行转换。JDK提供了两个类用于将字节流转换为字符流它们分别是InputStreamReader和OutputStreamWriter也称为转换流其作用如下所示。
1InputStreamReader是Reader的子类它可以将一个字节输入流转换成字符输入流方便直接读取字符。
2OutputStreamWriter是Writer的子类它可以将一个字节输出流转换成字符输出流方便直接写入字符。
Test
public void test(){File file new File(d:\\filetest\\hello.txt);try{// 创建一个字节输入流inFileInputStream in new FileInputStream(file);// 将字节输入流in转换成字符输入流isrInputStreamReader isr new InputStreamReader(in);int len isr.read();while(len ! -1){System.out.print((char)len);len isr.read();}isr.close();in.close();}catch (Exception e){System.out.println(e.getMessage());}
}
5. 序列化和反序列化
程序在运行过程中数据都保存在Java中的对象中内存但很多情况下我们都需要将一些数据永久保存到磁盘上。为此Java提供了对象序列化对象序列化可以将对象中的数据保存到磁盘。
5.1. 序列化和反序列化
对象序列化Serializable是指将一个Java对象转换成一个I/O流的字节序列的过程。
反序列化Deserialize是指将I/O流中的字节序列恢复为Java对象的过程。
5.2. Serializable接口和Externalizable接口
对象实现支持序列化机制这个对象所属的类必须是可序列化的。在Java中可序列化的类可通过实现Serializable或Externalizable两个接口之一。 Serializable接口 Externalizable接口 系统自动存储必要的信息 由程序员决定所存储的信息 Java内部支持易于实现只需实现该接口即可不需要其他代码支持 接口中只提供了两个抽象方法实现该接口必须要实现这两个抽象方法 性能较差 性能较好
5.3. 实现序列化方法
与实现Serializable接口相比虽然实现Externalizable接口可以带来一定性能上的提升但由于实现Externalizable接口需要实现两个抽象方法所以实现Externalizable接口也将导致编程的复杂度增加。在实际开发时大部分都采用实现Serializable接口的方式来实现对象序列化。使用Serializable接口实现对象序列化非常简单只需要让目标类实现Serializable接口即可无需实现任何方法。 Student类
public class Student implements Serializable {private static final long serialVersionUID 1L;private String name;public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic String toString() {return Student{ name name \ };}
} 测试类
public class TestDemo3 {Testpublic void test1(){Student student new Student();student.setName(张三);File file new File(d:\\filetest\\hello.txt);//向文件中写入数据try{ObjectOutputStream out new ObjectOutputStream(new FileOutputStream(file));out.writeObject(student);out.close();}catch (Exception e){System.out.println(e.toString());}}Testpublic void test2(){File file new File(d:\\filetest\\hello.txt);//向文件中写入数据try{ObjectInputStream in new ObjectInputStream(new FileInputStream(file));Student student (Student) in.readObject();System.out.println(student);in.close();}catch (Exception e){System.out.println(e.toString());}}
}
serialVersionUID适用于Java的对象序列化机制。简单来说Java的对象序列化机制是通过判断类的serialVersionUID来验证版本一致性。在进行反序列化时JVM会把字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较如果相同就认为是一致的可以进行反序列化否则就会抛出序列化版本不一致的异常。因此为了在反序列化时确保序列化版本的兼容性最好在每一个要序列化的类中加入private static final long serialVersionUID的变量值具体数值可自定义默认是1L。