Java实现文件写入——输入输出流(IO流)

输入输出含义和意义:

输入和输出功能是Java对程序处理数据能力的提高,java以流的形式处理数据。

流是一组有序的数据序列,根据操作类型,分为输入流和输出流。

程序从输入流读取数据,向输出流写入数据。

Java是面向对象的程序语言,每一个数据流都是一个对象,它们提供了各种支持“读入”与“写入”操作的流类。

 

Java的输入输出功能来自java.io 包中的InputStream类、OutputStream类、Reader类和Writer类以及继承它们的各种子类。

文件类(File类):

File类用于封装系统的文件和目录的相关信息。在该类中定义了一些与平台无关的方法来操作文件。例如文件的大小、修改时间、文件路径等。

//创建File对象的三种方法
new File (String pathName);

File file = new File("E://1.txt");
//parent :父抽象路径名   child:子路径名字符串
new File(String parent , String child);

File 类是对文件和文件夹的抽象,包含了对文件和文件夹的多种属性和操作方法。File类的常用方法如下表:

返回方法说明
StringgetName获取文件名称
StringgetParent获取文件的父路径字符串
StringgetPath获取文件的相对路径字符串
StringgetAbsolutePath获取文件的绝对路径字符串
booleanexists判断文件或者文件夹是否存在
booleanisFile判断是不是文件类型
booleanisDirectory判断是不是文件夹类型
booleandelete删除文件或文件夹,如果删除成功返回结果为true
booleanmkdir创建文件夹,创建成功返回true
booleansetReadOnly设置文件或文件夹的只读属性
longlength获取文件的长度
longlastModified获取文件的最后修改时间
String[ ]list获取文件夹中的文件和子文件夹的名称,并存放到字符串数组中
package com.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/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());

    }

}

运行结果为:

注意:在使用delete()方法删除File对象时,如果删除的对象是目录,该目录中的内容必须为空。

字节输入输出流:

字节流用于处理二进制数据的读取和写入,它以字节为单位,InputStream类和OutputStream类是字节流的抽象类,它们定义了数据流读取和写入的基本方法。各个子类会根据其特点实现或覆盖这些方法。

1、字节数入流抽象类InputStream

InputStream 类是字节输入流的抽象类,定义了操作输入流的各种方法,这些方法如下:

返回方法说明
intavailable()返回当前输入流的数据读取方法可以读取的有效字节数量
Abstract intread()从当前数据流中读取一个字节。若已达到流结尾,则返回-1
intread(byte[ ] bytes)从当前输入流读取一定的byte数据,并存取在数组中,然后返回读取的byte数据的数量,若已到达流结尾,则返回-1。
voidreset()将当前的输入流重新定位到最后一次调用mark()方法时的位置
voidmark(int readlimit)在当前输入流中做标记位置,当调用reset()方法时将返回到该位置,从标记位置开始,到再读入readlimit个字符为止,这个标记都维持有效。
BooleanmarkSupported()测试当前输入流是否支持mark()和reset()方法,只要其中一个不支持,则返回false
longskip(long n)跳过和丢弃当前输入的n个字节数据
voidclose()关闭当前输入流,并释放任何与之相关联的系统资源

InputStream 类是抽象类,不能通过new关键字来创建该实例对象,需要其子类创建该实例对象。

package com.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 block
            e.printStackTrace();
        }
    }
}

2、字节输出流抽象类OutputStream类

OutputStream定义了输出流的各种方法,如下表:

返回方法说明
voidwrite(byte[ ] b)将byte[ ] 数组中的数据写入当前输出流
voidwrite(byte[] b ,int off, int len)将byte[ ]数组下标off开始的len长度的数据写入当前输出流
Abstract voidwrite(int b)写入一个byte数据到当前输出流
voidflush()刷新当前输出流,并强制写入所有缓冲的字节数据
voidclose()关闭当前输出流

和InputStream类一样,OutputStream 类是抽象类,不能通过new关键字来创建该实例对象,需要其子类创建该实例对象。

使用InputStream从控制台获取用户输入的数据信息实例:

package com.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 block
        e.printStackTrace();
    }
    }
}

输出结果为:

3、文件字节输入流类 : FileInputStream类

文件字节输入流可以从指定路径的文件中读取字节数据

文件字节输入流继承InputStream类,并实现了读取输入流的各种方法。

// 文件字节输入流创建的构造方法语法

//以File对象为参数创建FileInputStream实例
new FileInputStream (File file);
//以文件对象的绝对路径为参数创建FileInputStream实例
new FileInputStream (String filePath);

4、 文件字节输出流类:FileOutputStream

文件字节输出流关联指定文件路径的文件,数据通过文件字节输出流以字节为单位输出并保存到文件中。

文件字节输出流继承自OutputStream类,并实现OutputStream类的各种方法。

//文件字节输出流的构造方法

//以File对象为参数创建FileOutputStream实例
new FileOutputStream (File file)
//以文件对象的绝对路径为参数创建FileOutputStream实例
new FileOutputStream (String filePath)

文件的写入和读取实例:

package com.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 block
            e.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 block
            e.printStackTrace();
        }
    }
}

字符输入输出流:

字符输入输出流和字节输入输出流有相同的功能,但传送数据的方式不一样,字节流以字节为单位传送数据,可以是任何类型的数据,例如:文本、音频、视频、图片等而字符流则以字符为单位传送数据,只能传送文本类型的数据

使用字符输入输出流的好处是:当读取中文时不会出现乱码问题,而使用字节输入输出流时,并不能保证这一点。

1、字符输入流抽象类:Reader类

该类定义了操作字符输入流的方法,如下表:

返回方法说明
booleanready()判断此数据流是否准备好
intread()读入一个字符,若已读到流结尾,则返回值为-1
intread(char[ ])读取一些字符到char[ ]数组内,并返回所读入的字符的数量,若已到达流结尾,则返回-1
Abscract intread(char[ ] chars,int off,int len)读取一些字符到char[ ]数组下标从off开始到off+len的位置,并返回所读入的字符的数量,若已到达流结尾,则返回-1;
voidreset()将当前输入流重新定位到最后一次mark()方法时的位置
voidmark(int readLimit)将当前输入流中做标记,当调用reset方法时将返回到该位置,从标记位置开始,到再读入readLimit个字符为止,这个标记都维持有效
booleanmarkSupported测试当前输入流是否支持mark()方法和reset()方法。只要有一个方法不支持,则返回-1
longskip(long n)跳过参数n指定的字符数量,并返回所跳过字符的数量
Abstract voidclose()关闭字符输入流,并释放与之关联的所有资源

2、字符输出流抽象类:Writer类

Writer 类主要是用于解决字符输入流的类,其地位与Reader类在输入流的地位和作用是相同的,也是所有字符输出流的流类。 
Writer类的主要方法如下:

返回方法说明
voidwrite(char[ ] cbuf)将字符数组的数据写入字符输出流
Abstract voidwrite(char[ ] cbuf int off ,int len)将字符数组从下标off 开始向输入流写入长度为len的数据
voidwrite(int c )向字符输入流中写入一个字符数据
voidwrite(String str )向输入流中写入一个字符串数据
voidwrite(String str , int off ,int len)向输入流中写入一个字符串从off 开始长度为len的数据
Abstract voidflush()刷新当前输出流,并强制写入所有缓冲区的字节数据
voidclose()向输出流中写入缓冲区的数据,然后关闭当前输出流,释放所有与当前输出流相关联的系统资源

3、文件字符输入流FileReader

       文件字符输入流与文件字节输入流的功能相似,但是传送数据的方式不一样,字节流以字节为单位传送数据,可以使文本、视频、音频、图片等。字符流以字符为单位传送数据,只能传送文本类型的数据。

//创建字符输入流常用构造方法
new FileReader(File file);

new FileReader(String path);

FileReader类读取指定磁盘文件内容的实例

package com.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 block
                e.printStackTrace();
            }
        }
    }
}

运行结果为:

    

4、文件字符输出流FileWriter

文件字符输出流继承了Writer类,提供了向文件输出的各种方法,数据通过文件字符输出流以字符为单位输出并保存到文件中。

package com.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 block
            e.printStackTrace();
        }
    }
}

运行后创建了Word2.txt 文件,并向其中写入数据 

IO流实战:

1、Java IO流实现复制文件夹

       通过IO不仅可以复制文件,还可以复制文件夹,但是文件夹内,可能包含其他文件夹,因此需要对他们进行分别复制。

package com.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 block
                    e.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.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 block
            e.printStackTrace();
        }
    }
}

3、删除指定文件

       File类的delete()方法可以实现删除指定的文件,首先使用目标文件路径创建File类的实例对象,然后再调用File类的delete()方法。

package com.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("文件删除失败!");
        }
    }
}

 

相关推荐
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页