输入输出的重要性:
输入和输出功能是Java对程序处理数据能力的提高,Java以流的形式处理数据。流是一组有序的数据序列,根据操作的类型,分为输入流和输出流。
程序从输入流读取数据,向输出流写入数据。Java是面向对象的程序语言,每一个数据流都是一个对象,它们提供了各种支持“读入”与“写入”操作的流类。
Java的输入输出功能来自java.io 包中的InputStream类、OutputStream类、Reader类和Writer类以及继承它们的各种子类。
(一)解析文件处理的奥秘
1、学习使用文件类 : File类
File类用于封装系统的文件和目录的相关信息。在该类中定义了一些与平台无关的方法来操作文件。例如文件的大小、修改时间、文件路径等。
创建 File 对象可以通过下面3种方式:
2、如何获取文件信息
File 类是对文件和文件夹的抽象,包含了对文件和文件夹的多种属性和操作方法。File类的常用方法如下表:
下面通过实例介绍File类获取文件信息
package com.zch.io;import java.io.File;import java.util.Date;/*** 在src根目录下创建FileInfo类,在该类的主方法中创建文件对象,通过File类的相关方法,获取文件的相关信息* */public class FileInfo {public static void main(String[] args) {String filePath = "src/com/zch/io/FileInfo.java";// 根据指定路径创建文件对象File file = new File(filePath);System.out.println("文件名称:" + file.getName());System.out.println("文件是否存在:" + file.exists());System.out.println("文件的相对路径:" + file.getPath());System.out.println("文件的绝对路径:" + file.getAbsolutePath());System.out.println("是否为可执行文件:" + file.canExecute());System.out.println("文件可以读取:" + file.canRead());System.out.println("文件可以写入:" + file.canWrite());System.out.println("文件上级路径:" + file.getParent());System.out.println("文件大小:" + file.length() + "B");System.out.println("文件最后修改时间:" + new Date(file.lastModified()));System.out.println("是否文件类型:" + file.isFile());System.out.println("是否为文件夹:" + file.isDirectory());}}
运行结果如下:
文件名称:FileInfo.java文件是否存在:true文件的相对路径:src\com\zch\io\FileInfo.java文件的绝对路径:D:\Java\IO\src\com\zch\io\FileInfo.java是否为可执行文件:true文件可以读取:true文件可以写入:true文件上级路径:src\com\zch\io文件大小:1195B文件最后修改时间:Sat 03 21:30:10 CST 是否文件类型:true是否为文件夹:false
在使用delete()方法删除File对象时,如果删除的对象是目录,该目录中的内容必须为空。
(二)使用字节输入输出流
字节流用于处理二进制数据的读取和写入,它以字节为单位,InputStream类和OutputStream类是字节流的抽象类,它们定义了数据流读取和写入的基本方法。各个子类会依其特点实现或覆盖这些方法。
1、字节数入流抽象类InputStream
InputStream 类是字节输入流的抽象类,定义了操作输入流的各种方法,这些方法如表:
InputStream 类是抽象类,不能通过new关键字来创建该实例对象,需要其子类创建该实例对象。下面通过实例如何使用InputStream从控制台获取用户输入的数据信息。
package com.zch.io;import java.io.IOException;import java.io.InputStream;/*** 创建InputStream实例inp,并将其赋值为System类的in属性,定义为控制台输入流,从inp输入流中获取字节信息,* 用这些字节信息创建字符串,并将其在控制台上输出。*/public class InputMessage {public static void main(String[] args) {InputStream inp = System.in;byte[] bytes = new byte[1024];try {while(inp.read() != -1){//根据用户输入的信息创建字符串String str = new String(bytes).trim();}inp.close();//关闭流} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
2、字节输出流抽象类OutputStream类
OutputStream定义了输出流的各种方法,如下表:
和InputStream类一样,OutputStream 类是抽象类,不能通过new关键字来创建该实例对象,需要其子类创建该实例对象。
package com.zch.io;import java.io.IOException;import java.io.OutputStream;/*** 创建OutputStream实例out,并将其赋值为System.out标准输出流。通过write()方法向流写入数据。*/public class OutputData {public static void main(String[] args) {OutputStream output = System.out;//实例化OutputStream对象byte[] bytes = "使用OutputStream输出流在控制台输出字符串\n".getBytes();//创建bytes数组try {output.write(bytes);bytes = "输出内容:\n".getBytes();output.write(bytes); //向流中写入数据bytes = "Java数据交互管道——IO流 \n".getBytes();output.write(bytes);output.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
输出结果如下:
使用OutputStream输出流在控制台输出字符串输出内容:Java数据交互管道——IO流
3、文件字节输入流类 : FileInputStream类
文件字节输入流可以从指定路径的文件中读取字节数据。文件字节输入流类继承InputStream类,并实现了读取输入流的各种方法。
创建文件字节输入流创建的构造方法语法如下:
语法1:以File对象为参数创建FileInputStream实例
new FileInputStream(File file)
语法2:以文件对象的绝对路径为参数创建FIleInputStream实例
new FileInputStream(String filepath)
4、文件字节输出流类:FileOutputStream
文件字节输出流关联指定文件路径的文件,数据通过文件字节输出流以字节为单位输出并保存到文件中。文件字节输出流继承自OutputStream类,并实现OutputStream类的各种方法。
文件字节输出流的构造方法语法如下:
语法1:以File对象为参数创建FileOutputStream实例
new FileOutputStream(File file)
语法2:以文件对象的绝对路径为参数创建FIleOutputStream实例
new FileOutputStream(String filepath)
下面通过实例介绍文件的写入和读取:
package com.zch.io;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/*** 创建OutputStream实例out,并将其赋值为System.out标准输出流,通过write方法向流中写入数据* */public class FileCreate {public static void main(String[] args) {File file = new File("D:/", "word.txt"); //创建文件对象try {if (!file.exists()) {//如果文件不存在则新建文件file.createNewFile();}FileOutputStream output = new FileOutputStream(file);byte[] bytes = "Java数据交流管道——IO流".getBytes();output.write(bytes);//将数组的信息写入文件中output.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {FileInputStream input = new FileInputStream(file);byte[] bytes2 = new byte[1024];int len = input.read(bytes2);System.out.println("文件中的信息是:" + new String(bytes2, 0, len));input.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
(三) 使用字符输入输出流
字符输入输出流 与 字节输入输出流有相同的功能,但传送数据的方式不一样,字节流以字节为单位传送数据,可以使任何类型的数据,例如文本、音频、视频、图片等。字符流以字符为单位传送数据,只能传送文本类型的数据。使用字符输入输出流的好处是,当读取中文时不会出现乱码问题,而使用字节输入输出流时,却不能保证这一点。
1、字符输入流抽象类:Reader类
该类定义了操作字符输入流的方法,如下表:
2、字符输出流类Writer类
Writer 类主要是用于解决字符输入流的类,其地位与Reader类在输入流的地位和作用是相同的,也是所有字符输出流的流类。
Writer类的主要方法如下:
3、文件字符输入流FileReader
文件字符输入流与文件字节输入流的功能相似,但是传送数据的方式不一样,字节流以字节为单位传送数据,可以使文本、视频、音频、图片等。字符流以字符为单位传送数据,只能传送文本类型的数据。
创建字符输入流常用的构造方法:
语法1:
new FileReader(File file);
语法2:
new FileReader(String path);
下面通过实例介绍FileReader类读取指定磁盘文件的内容。
package com.zch.io;import java.io.File;import java.io.FileReader;public class FileInAndOut {public static void main(String[] args) {//定义指定磁盘的文件的File对象File file = new File("D://word.txt");if(! file.exists()){System.out.println("对不起,不包含指定路径的文件");}else{//根据指定路径的File对象创建FileReader对象try {FileReader fr = new FileReader(file);char[] data = new char[23];//定义char数组int length = 0;while((length = fr.read(data))>0){//循环读取文件中的数据String str = new String(data,0,length);//根据读取文件的内容创建String 对象System.out.println(str);//输出读取内容}fr.close();//关闭流} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
运行结果如下图:
4、文件字符输出流FileWriter
文件字符输出流继承自Writer类,提供了向文件输出的各种方法,数据通过文件字符输出流以字符为单位输出并保存到文件中。
package com.zch.io;/*** 通过给定的String类型参数的指定文件名称与路径,创建FileWriter类。*/import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class FileWriterDemo {public static void main(String[] args) {File file = new File("D://word2.txt");//创建指定文件try {if(! file.exists()){file.createNewFile();//如果指定文件不存在,新建文件}FileReader fr = new FileReader("D://word.txt");FileWriter fw = new FileWriter(file);//创建FileWriter对象int length = 0;while((length = fr.read()) != -1){//如果没有读到文件末尾fw.write(length);//向文件写入数据}fr.close();//关闭流fw.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
运行后创建了Word2.txt 文件,并向其中写入数据
(四)IO流实战:
1、Java IO流实现复制文件夹
通过IO不仅可以复制文件,还可以复制文件夹,但是文件夹内,可能包含其他文件夹,因此需要对他们进行分别复制。
package com.zch.io;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;public class CopyFile {public static void main(String[] args) {File sourceFile = null;File desFile = null;String sourceFolder = "D://简历2";String copyFolder = "D://copy";sourceFile = new File(sourceFolder);if (!sourceFile.isDirectory() || !sourceFile.exists()) {System.out.println("源文件夹不存在!");} else {desFile = new File(copyFolder);desFile.mkdir();copy(sourceFile.listFiles(), desFile);System.out.println("文件夹复制成功!");}}/*** 创建copy方法,该方法接收文件数组和目标文件夹两个参数,如果目标文件夹不存在,则调用mkdir()方法创建文件夹,然后再循环中将文件数组* 中的每个文件对象写到目标文件夹内。* @param fl* @param file*/public static void copy(File[] fl, File file) {if (!file.exists()) {// 如果文件夹不存在file.mkdir(); // 建立新的文件夹}for (int i = 0; i < fl.length; i++) {if (fl[i].isFile()) {// 如果是文件类型,则复制文件try {FileInputStream fis = new FileInputStream(fl[i]);FileOutputStream out = new FileOutputStream(new File(file.getPath() + File.separator + fl[i].getName()));int count = fis.available();byte[] data = new byte[count];if ((fis.read(data)) != -1) {out.write(data);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (fl[i].isDirectory()) {// 如果是文件夹类型File des = new File(file.getPath() + File.separator+ fl[i].getName());des.mkdir(); // 在目标文件夹中创建相同的文件夹copy(fl[i].listFiles(), des); // 递归调用方法本身}}}}
运行本实例,会将D盘中的简历文件中的内容复制到D盘的copy文件夹中,而且包含文件夹的子文件夹
2、Java IO流实现分行向文件中写入数据
FileWriter类可以向文件写入字符数据,如果将FileWriter类封装到BufferWriter类的缓冲字符流中,能够实现缓冲字符输出流,并且可以通过读输出流的newLine()方法,来实现数据的分行写入。
package com.zch.io;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;/*** 创建BranchWriter类,在主方法中定义文件对象,将该对象作为参数创建BufferedWriter类实例,* 调用该实例的writer方法将数据写入文件中,然后 调用newLine()方法写入换行符,实现分行向文件写入数据。* */public class BranchWriter {public static void main(String[] args) {String filePath = "D://BranchWriter.txt";File file = new File(filePath);try {if (!file.exists()) {file.createNewFile();}FileWriter fw = new FileWriter(file); // 创建文件输出流BufferedWriter bw = new BufferedWriter(fw); // 使用缓冲区数据流封装输出流for (int i = 0; i < 100; i++) {//循环写入100行数据bw.write("Java交互管道——IO流".toCharArray());// 写入数据到输出流bw.newLine(); // 写入换行符bw.flush(); // 刷新缓冲区}System.out.println("成功写入数据!");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
3、删除指定文件
File类的delete()方法可以实现删除指定的文件,首先使用目标文件路径创建File类的实例对象,然后再调用File类的delete()方法。
package com.zch.io;import java.io.File;public class FileDelete {public static void main(String[] args) {String filePath = "D://word.txt";File file = new File(filePath);delFile(file);}public static void delFile(File file) {if (!file.exists()) {System.out.println("文件不存在!");return;}boolean rs = file.delete();if (rs) {System.out.println("文件删除成功!");} else {System.out.println("文件删除失败!");}}}