10Java 输入输出流篇


I/O

物质在目的地之间的转移运动称为流,可分为 输入流 、 输出流

输入流:程序从源中读取数据

输出流:数据要到达的目的地

主要流:

文件流
缓冲流
数据流

输入流

InputStream类 是字节流 的抽象类,所有字节输入流的父类 java.io.InputStream

Reader类 是字符流 的抽象类 ,是Unicode编码,适合处理文本,所有字符输入流的父类 java.io.Reader

提供的方法

修饰符 方法 说明
void close() 关闭输入流
void mark(int readlimit) 标记输入流中的当前位置
boolean markSupported() 支持 mark和 reset方法,则true
int read() 从输入流读取数据,(字节)0~255范围,没有则-1
int read(E[] b) 从输入流读取一些 字符/字节 ,并将它们存储到缓冲区b
void reset() 将流重新定位到上次输入流调用 mark方法时的位置
long skip(long n) 跳过输入流上的n个字符,返回实际跳过的字节数

输出流

OutputStream类 是字节流 的抽象类,所有字节输出流的父类 java.io.OutputStream

Writer类 是字符流 的抽象类 ,所有字符输入流的父类 java.io.Writer

提供的方法

修饰符 方法 说明
void close() 关闭流
void flush() 完成输出清空缓冲
void write(E text) 将指定text写入流
void write(E[] b) 将b数组写入流
void write(E[] b , int off , int len) 将b数组中从偏移量off开始写入len个字节的流

File类

File类是代表磁盘的文件或者文件夹(目录),该类可实现创建、删除、重命名文件等操作

构造方法

File(String pathname) 指定路径名 字符串转换为 抽象路径 来创建新File实例

File(String parent , String child) 路径名 的字符串 和 文件名字符串 来创建新File实例

File(String f, String child) 抽象路径名 和 文件名字符串 来创建新File实例

pathname:路径名称(包含文件名)

parent:父路径字符串,例如:D:/doc

child:子路径字符串 ,例如:no1.txt

f:父路径对象

以下代码 构造方法创建

import java.io.File;

public class Demo {
    public static void main(String[] args) {

        //以项目本身为根路径进行查找文件
        File f1 = new File("/src/deoc.txt");
        //输出绝对路径
        System.out.println("f1:"+f1.getAbsolutePath());

        File f2 = new File("E:\\Java\\Study\\15Chapter (输入输出流)\\15.3.1 File创建\\src\\","deoc.txt");
        //输出绝对路径
        System.out.println("f2:"+f2.getAbsolutePath());

        File f = new File("E:\\Java\\Study\\15Chapter (输入输出流)\\15.3.1 File创建\\src\\");
        File f3 = new File(f , "deoc.txt");
        //输出绝对路径
        System.out.println("f3:"+f3.getAbsolutePath());

        //路径是否一样
        System.out.println(f1.equals(f2));
        System.out.println(f2.equals(f3));
    }
}

运行结果

f1:E:\src\deoc.txt
f2:E:\Java\Study\15Chapter (输入输出流)\15.3.1 File创建\src\deoc.txt
f3:E:\Java\Study\15Chapter (输入输出流)\15.3.1 File创建\src\deoc.txt
false
true

说明:

  • 盘符的路径名前缀由驱动器号和 :组成
  • 路径分割一般用: \//
  • 子路径文件一定要有后缀,如:.jpg.txt

文件操作及获取信息

File类提供以下为常用方法 ,如果想看更多方法自行查JDK文档

修饰符 方法 说明
String getName() 获取文件名称
boolean canRead() 判断文件是否为可读
boolean canWrite() 判断文件是否可写入
boolean exists() 判断文件是否存在
long length() 获取文件的长度(字节为单位)
String getAbsolutePath() 获取文件的绝对路径
String getParent() 获取文件的父路径
boolean isFile() 判断文件是否存在(普通文件)
boolean isDirectory() 判断文件是否为一个目录
boolean isHidden() 判断文件是否为隐藏文件
long lastModified() 获取文件最后修改时间(毫秒为单位)
boolean createNewFile() 路径文件不存在,则创建新的空文件
boolean delete() 删除子路径(最后一个)文件或文件夹
boolean mkdir() 创建抽象路径名命名的目录
boolean mkdirs() 创建抽象路径名命名的目录,包括任何必需但不存在的父目录
File[] listFiles() 返回文件夹所有子文件夹

以下代码 测试File类方法的使用

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo {
    public static void main(String[] args) throws IOException {

        File f = new File("src/","doc.txt");
        //会在项目里的根路经的src文件夹里常见doc.txt文件
        System.out.println("文件不存在,则创建新文件? "+f.createNewFile());

        System.out.println("获取文件名称:"+f.getName());

        System.out.println("文件是否可读?  "+f.canRead());

        System.out.println("文件是否可写?  "+f.canWrite());

        System.out.println("判断文件是否存在? "+f.exists());

        System.out.println("输出文件长度:"+f.length());

        System.out.println("输出文件路径:"+f.getAbsolutePath());

        System.out.println("输出文件父路径:"+f.getParent());

        System.out.println("判断文件是否存在(普通文件)?"+f.isFile());

        System.out.println("文件是否为一个目录?"+f.isDirectory());

        System.out.println("文件是否为隐藏文件?"+f.isHidden());

        System.out.println("输出文件最后修改时间戳:"+f.lastModified());
        Date date = new Date(f.lastModified());
        SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm");

        System.out.println("输出文件最后修改时间:"+sdf.format(date));

//        System.out.println("删除文件?"+f.delete());

        //创建的是文件夹
        // mkdir    (创建单个)
        // mkdirs   (创建多个)
        System.out.println("创建抽象路径名命名的目录?"+f.mkdir());

        //创建在与项目根路经
        File fm = new File("cs1/cs2/cs3/");
        System.out.println("创建抽象路径名命名的目录?"+fm.mkdirs());


        System.out.println("===================");
        //listFiles方法测试
        //项目根路经
        File file = new File("");
        //获取项目根路经(防止空指针异常)
        File file2 = new File(file.getAbsolutePath());
        //file2抽象路径必须为绝对路径否则空指针异常
        File[] files = file2.listFiles();
        for (File tmp : files){
            if (tmp.isFile()){
                System.out.println("文件:"+tmp.getName());
            }else{
                System.out.println("文件夹:"+tmp.getName());
            }
        }

    }
}

运行结果

文件不存在,则创建新文件? false
获取文件名称:doc.txt
文件是否可读?  true
文件是否可写?  true
判断文件是否存在? true
输出文件长度:0
输出文件路径:E:\Java\Study\15Chapter (输入输出流)\15.3.2 File方法\src\doc.txt
输出文件父路径:src
判断文件是否存在(普通文件)?true
文件是否为一个目录?false
文件是否为隐藏文件?false
输出文件最后修改时间戳:1594525019225
输出文件最后修改时间:20/07/12 11:36
创建抽象路径名命名的目录?false
创建抽象路径名命名的目录?false
===================
文件夹:.idea
文件:15.3.2 File方法.iml
文件夹:cs1
文件夹:out
文件夹:src

字节流

FileInputStream、FileOutputStream类 操作磁盘文件

字节输出流

Class FileOutputStream

java.lang.Object
java.io.OutputStream
java.io.FileOutputStream

构造方法

FileOutputStream(File file)

FileOutputStream(String name)

FileOutputStream(String name , boolean append)

FileOutputStream(File file , boolean append)

name:给文件名创建FileInputStream对象
file:抽象路径对象创建FileInputStream对象
append:是否连续写入数据

常用方法

修饰符 方法 说明
void close() 关闭流
void write(byte[] b) 指定字节数组写入文件
void write(byte[] b , int off , int len) 指定范围写入字节数组
void write(int b) 将指定字节写入

以下代码 写入数据

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo {
    public static void main(String[] args){

        //FileOutputStream输出流数据(写入数据)
        //项目根路经
        File file = new File("");
        //获取项目根路经(防止空指针异常)
        File wj = new File(file.getAbsolutePath(),"test.txt");
        FileOutputStream out = null;

        try {
            //判断文件是否存在
            if (wj.exists()){
                //实例化
                out = new FileOutputStream(wj,true);
            }else{
                //新建文件
                wj.createNewFile();
                //实例化
                out = new FileOutputStream(wj,true);
            }

            String str = "我喜欢学习Java编程语言!";
            //将字符串转换为字节数组
            byte[] bytes = str.getBytes();

            //写入数据
            out.write(bytes);

            //关闭流
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

运行结果

在项目创建了test.txt文件,并写入数据 “我喜欢学习Java编程语言!” (我运行了3次)

字节输入流

Class FileInputStream

java.lang.Object
java.io.InputStream
java.io.FileInputStream

构造方法

FileInputStream(File file)

FileInputStream(String name)

FileInputStream(String name , boolean append)

FileInputStream(File file , boolean append)

name:给文件名创建FileInputStream对象
file:抽象路径对象创建FileInputStream对象
append:是否连续写入数据

常用方法

修饰符 方法 说明
void close() 关闭流
long length() 返回底层文件的长度
int read() 从流中读取一字节
int read(byte[] b , int off , int len) 从流中读取off到len位置的字节
void seek(long pos) 将当前流位置为所需位置

以下代码 读取文件

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) {

        //FileInputStream字节输入流(读取文件)
        //项目根路经
        File file = new File("");
        //获取项目根路经(防止空指针异常)
        File wj = new File(file.getAbsolutePath(),"test.txt");
        FileInputStream input = null;

        try {
            if (wj.exists()){
                //实例化
                input = new FileInputStream(wj);
            }else{
                //新建文件
                wj.createNewFile();
                //实例化
                input = new FileInputStream(wj);
            }
            //创建缓冲区
            byte[] bytes = new byte[1024];
            int len = input.read(bytes);
            String str = new String(bytes,0,len);
            System.out.println("文件内容为:"+str);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

运行结果

文件内容为:我喜欢学习Java编程语言!我喜欢学习Java编程语言!我喜欢学习Java编程语言!

字符流

字符输入输出流可避免像字节流出现乱码现象!他们是使用方法是大致一样!

字符输出流

Class FileWriter

java.lang.Object
java.io.Writer
java.io.OutputStreamWriter
java.io.FileWriter

以下代码 写入文件

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) {

        File file = new File("word.txt");
        FileWriter fw = null;

        try {
            fw = new FileWriter(file);

            String str = new String("欢迎来到,我的世界");
            fw.write(str);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fw != null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

运行结果

在项目根路径创建 word.txt文件 并写入 “欢迎来到,我的世界”

字符输入流

Class FileReader

java.lang.Object
java.io.Reader
java.io.InputStreamReader
java.io.FileReader

以下代码 读取文件

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Demo {
    public static void main(String[] args) {

        File file = new File("word.txt");
        FileReader fr = null;

        try {
            fr = new FileReader(file);

            char[] ch = new char[1024];

            int  count = fr.read(ch);
            String str = new String(ch , 0 , count);
            System.out.println("文件内容: "+str);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr != null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

运行结果

文件内容: 欢迎来到,我的世界

缓存字节流

缓存是输入输出流的优化,能大大提升传输效率!

创建构造方法时未定义大小,缓冲大小会默认为 32个字节 做缓存大小

传输形式

文件→字节流→缓存流→目的地

缓存字符输出流

Class BufferedOutputStream

java.lang.Object
java.io.OutputStream
java.io.FilterOutputStream
java.io.BufferedOutputStream

构造方法

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out , int size)

out:文件输出流
size:缓储存大小

以下代码 写入文件

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        //文件选择大文件为好,容易体现效果
        File field = new File("word.txt");
        FileOutputStream out = null;
        //创建缓存输出流
        BufferedOutputStream buffout = null;
        //时间记录点1
        long a = System.currentTimeMillis();

        try {
            out = new FileOutputStream(field,true);
            //用缓存输出流封装输出流
            buffout = new BufferedOutputStream(out);

            String str = new String("世界你好!\n");
            byte[] bytes = str.getBytes();

            //写入99999次
            for (int i = 0; i < 99999; i++) {

                //单选程序测试

                /*
                *
                * 选择(1)缓存流测试速度
                *
                *  */
                //使用流时是使用缓存输出流
                buffout.write(bytes);
                //刷新。强制将缓冲区数据写入文件中,即使缓冲区没有写满
                // 缓存区没写满刷新传输,提升效率
                buffout.flush();

                /*
                 *
                 * 选择(2)字节流测试速度
                 *
                 *  */
//                out.write(bytes);
            }
            //时间记录点2
            long b = System.currentTimeMillis();
            System.out.println("运行了:"+(b-a)+"mm");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (buffout != null){
                try {
                    buffout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

缓存流输出还是大文件较好,文件选择建议自选大文件为好呈现

缓存字符输入流

Class BufferedInputStream

java.lang.Object
java.io.InputStream
java.io.FilterInputStream
java.io.BufferedInputStream

构造方法

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in , int size)

in:文件输出流
size:缓储存大小

import java.io.*;

public class Demo2 {

    public static void main(String[] args) {
        //文件选择大文件为好,容易体现效果
        File field = new File("word.txt");
        FileInputStream input= null;
        BufferedInputStream buffin = null;

        //时间记录点1
        long a = System.currentTimeMillis();
        try {
            input = new FileInputStream(field);
            buffin = new BufferedInputStream(input);

            //缓冲区字节数组(与buffered不同)
            byte[] bytes = new byte[1024];

            /*
             *
             * 选择(1)缓存流测试速度
             *
             *  */
            //直到读完
            while ((buffin.read(bytes))!= -1){ }

            /*
             *
             * 选择(2)字节流测试速度
             *
             *  */
            //直到读完
//            while ((input.read(bytes))!= -1){ }

            long b = System.currentTimeMillis();
            System.out.println("运行了:"+(b-a)+"mm");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (input != null){
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (buffin != null){
                try {
                    buffin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

运行结果 当然是缓存流比字节流快啦,前提是大文件!

缓存字符流

可以以行为单位进行 输入/输出 ,与以上的缓冲字符流大部分相同!

缓存字符输出流

Class BufferedWriter

java.lang.Object
java.io.Writer
java.io.BufferedWriter

构造方法与以上的一样!

缓存字符输出流提供独有方法:newLine() 写入一行(换行) 带分割符

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo {
    public static void main(String[] args) {

        File file = new File("word.txt");

        FileWriter fw= null;
        BufferedWriter bfw = null;

        try {
            //先创建后关闭
            fw = new FileWriter(file);
            bfw = new BufferedWriter(fw);

            String str = new String("世界这么大,");
            String str2 = new String("我想去看看。");

            bfw.write(str);//写入数据
            bfw.newLine();//创建新行
            bfw.write(str2);//写入数据

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //先创建后关闭
            if (bfw != null){
                try {
                    bfw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fw != null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

在项目创建了test.txt文件,并写入数据 “世界这么大,\n我想去看看。”

缓存字符输入流

Class BufferedReader

java.lang.Object
java.io.Reader
java.io.BufferedReader

缓存字符输入流提供独有方法:String readLine() 读取一个文本行

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) {

        File file = new File("word.txt");

        FileReader fr = null;
        BufferedReader bfr = null;

        try {

            fr = new FileReader(file);
            bfr = new BufferedReader(fr);

            String tmp = null;
            //计数变量
            int i = 1 ;
            //逐行获取字符串并输出
            while ((tmp = bfr.readLine()) != null){
                System.out.println("第"+(i++)+"行:"+tmp);
            }


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bfr != null){
                try {
                    bfr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fr != null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

运行结果

第1行:世界这么大,
第2行:我想去看看。

数据流

允许应用程序以与机器无关的方式从底层输入流中读取基本java数据类型

数据输出流

Class DataOutputStream

java.lang.Object
java.io.OutputStream
java.io.FilterOutputStream
java.io.DataOutputStream

构造方法

DataOutputStream(OutputStream out)

out:底层输出流,保存供以后使用

DataOutputStream类提供了以下独有方法

修饰符 方法 说明
void writeBoolean(boolean v) 将 boolean写入底层输出流(1字节)
void writeByte(int v) 将 byte值写入底层输出流(1字节)
void writeBytes(String s) 将字符串作为字节序列写入基础输出流
··· ··· ···多余自行查询 JDK文档
void writeUTF(String str) 使用 modified UTF-8编码以机器无关的方式将字符串写入基础输出流

数据输入流

Class DataInputStream

java.lang.Object
java.io.InputStream
java.io.FilterInputStream
java.io.DataInputStream

构造方法

DataInputStream(InputStream in)

in:指定的输入流

import java.io.*;

public class Demo {
    public static void main(String[] args) {

        File file = new File("word.txt");

        //创建字节流
        FileOutputStream out = null;
        FileInputStream inp = null;
        //创建数据流
        DataOutputStream dataout = null;
        DataInputStream datainp = null;

        try {
            out = new FileOutputStream(file);
            dataout = new DataOutputStream(out);

            inp = new FileInputStream(file);
            datainp = new DataInputStream(inp);

            //写入数据
            dataout.writeUTF("使用writeUTF方法写入!");
            dataout.writeChars("使用writeChars方法写入!");
            dataout.writeBytes("使用writeBytes方法写入!");

            //读取数据
            System.out.println("在输入流读取数据:"+datainp.readUTF());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (datainp != null){
                try {
                    datainp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inp != null){
                try {
                    inp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dataout != null){
                try {
                    dataout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

运行结果

在输入流读取数据:使用writeUTF方法写入!

文章作者: 柏竹
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 柏竹 !
评论
  目录