天天看点

JavaSE高级开发之I/O流(一)

java.io

包里的核心组成就是五个类(

File

OutputStream

InputStream

Writer

Reader

)。

1. File文件操作类

1.1 文件操作

Java.io

包之中,

File

类是唯一一个与文件本身操作(创建、删除、取得信息等)有关的程序类。

  • File

    类中关于文件有如下方法::

    ① 设置文件路径:

    File(String pathname)

    ② 设置父路径和子路径:

    File(String parent, String child)

    ③ 判断文件是否存在:

    exists()

    ④ 新建文件:

    createNewFile()

    ,只是创建文件本身,对于其内容并不做处理!

    ⑤ 删除文件:

    delete()

对于文件路径有以下要注意的点:

Windows

平台下使用的是 反斜杠,而在

Linux

系统下使用的是 “/” 。所以在使用路径分隔符时都会采用File类的一个常量

separator

来描述。它会根据平台而选定使用哪种分隔符。
package com.file;

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

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

        //将本地文件系统关联到Java的File对象,设置文件路径
        File file = new File("D:" + File.separator + "test.txt");
        
        //判断文件是否存在,如果存在则删除,如果不存在则新建
        if(file.exists()) {
            if(file.delete()) {
                System.out.println("文件已经存在并且删除成功");
            } else {
                System.out.println("文件已经存在但是删除失败");
            }
        } else {
            try {
                if(file.createNewFile()) {
                    System.out.println("文件不存在并且新建成功");
                } else {
                    System.out.println("文件不存在但是新建失败");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
           

1.2 目录操作

  • File

    类中关于目录有如下方法:

    mkdir()

    :只会创建当前目录,如果父目录不存在,则创建失败

    mkdirs()

    :创建目录时,如果父目录不存在,则一并创建
package com.file;

import java.io.File;

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

        File file = new File("D:" + File.separator + "a"
                + File.separator + "b");
		
		//mkdirs连a目录和b目录一起创建
        //如果目录存在则删除,如果不存在则创建
        if(file.exists()) {
            file.delete();
        } else {
            if(file.mkdirs()) {
                System.out.println("目录创建成功");
            } else {
                System.out.println("目录创建失败");
            }
        }
        
    }
}
           

1.3 获取文件信息

① 获得父路径:

getParent()

② 获得父

File

对象:

getParentFile()

③ 判断是否是文件:

isFile()

④ 判断是否是目录:

isDirectory()

⑤ 判断是否是隐藏文件:

isHidden()

⑥ 获取文件大小(字节数):

length()

⑦ 最后一次修改日期:

lastModified()

⑧ 列出目录中的全部组成:

listFiles()

package com.file;

import java.io.File;
import java.util.Date;

public class TestFile {
    public static void main(String[] args) {
        
        File file = new File("D:" + File.separator + "a" + File.separator + "b");

        //文件信息
        System.out.println("是否存在:" + file.exists());
        System.out.println("是否是文件:" + file.isFile());
        System.out.println("是否是目录:" + file.isDirectory());
        System.out.println("是否是隐藏文件:" + file.isHidden());
        System.out.println("文件大小(字节):" + file.length());
        System.out.println("最近的修改时间:" + new Date(file.lastModified()));

        //遍历目录(在a/b里面又手动添加了一个test.txt文件后进行此过程)
        if (file != null && file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    System.out.println("父路径:" + f.getParent() + " 文件名:" + f.getName() + " 文件绝对路径:" + f.getAbsolutePath());

                }
            }
        }
    }
}
           
JavaSE高级开发之I/O流(一)

2. 字节流与字符流

java.io

包中,流分为两种:字节流(

InputStream

OutputStream

)和字符流(

Reader

Writer

)。又或者分为输入流(

InputStream

Reader

)和输出流(

OutputStream

Writer

)。

JavaSE高级开发之I/O流(一)
JavaSE高级开发之I/O流(一)

File

类本身不支持文件内容处理,如果要处理文件内容,则必须要通过流的操作模式来完成。字节流与字符流操作的本质区别只有一个:字节流是原生的操作,而字符流是经过处理后的操作。

  • 不管使用的是字节流还是字符流,其基本的操作流程几乎是一样的,以

    File

    类文件操作为例:

    ① 根据文件路径创建

    File

    类对象

    ② 根据字节流或字符流的子类实例化父类对象

    ③ 进行数据的读取或写入操作

    ④ 关闭流(

    close()

    )(对于IO操作属于资源处理,所有的资源处理操作(IO操作、数据库操作、网络)最后必须要进行关闭)

2.1 字节输出流(OutputStream)

OutputStream类的定义结构:
public abstract class OutputStream implements Closeable, Flushable

OutputStream类实现了Closeable,Flushable两个接口,这两个接口中的方法有:
1. Closeable: public void close() throws IOException;
2. Flushable: public void flush() throws IOException;
           
  • 我们可以看到

    OutputStream

    是一个抽象类,所以要想实例化,就必须要使用子类。如果要进行文件的操作,可以使用

    FileOutputStream

    类来处理,这个类的构造方法如下:

    ① 接收

    File

    类(覆盖):

    FileOutputStream(File file)

    ② 接收

    File

    类(追加):

    FileOutputStream(File file, boolean append)

    ,默认是

    false

    !!
  • OutputStream

    类中进行定义的方法还有:

    ① 将给定的字节数组内容全部输出:

    write(byte b[])

    ② 将部分字节数组内容输出:

    write(byte b[], int off, int len)

    ③ 输出单个字节:

    write(int b)

package com.file;

import java.io.*;

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

        String directory = "D:" + File.separator + "a" + File.separator + "b";
        File file = new File(directory, "test.txt");

        OutputStream out = null;

        try {

            out = new FileOutputStream(file);


            //将给定的字节数组内容全部输出
            out.write("Java is best".getBytes());

            //单个字节
            out.write("\n".getBytes());

            //ASCII int
            out.write(49);

            //将部分字节数组内容输出
            byte[] buff = "HelloWorld".getBytes();
            out.write(buff, 2, 5);

            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
           
JavaSE高级开发之I/O流(一)
AutoCloseable自动关闭资源

JDk1.7

开始追加了一个

AutoCloseable

接口,这个接口的主要目的是自动进行关闭处理。这种自动关闭处理是需要结合

try

语句进行调用,必须在try中定义对象。

下述操作直接使用自动关闭官员的形式,所以这里不再详细赘述!!

2.2 字节输入流(InputStream)

InputStream类的定义结构:
public abstract class InputStream implements Closeable

InputStream类只实现了Closeable接口。
           
  • OutputStream

    的使用一样,

    InputStream

    也是一个抽象类,如果要对其实例化,同样也需要使用子类。如果要对文件进行处理,则使用

    FileInputStream

    类。
  • InputStream

    类中提供的方法有:

    ① 读取数据到字节数组中:

    read(byte b[])

    ② 读取部分数据到字节数组中:

    read(byte b[], int off, int len)

    ③ 读取单个字节:

    read()

package com.file;

import java.io.*;

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

        String directory = "D:" + File.separator + "a" + File.separator + "b";
        File file = new File(directory, "test.txt");

        try(InputStream in = new FileInputStream(file)) {

            byte[] data = new byte[7];
            int len = in.read(data);
            System.out.println("读取数据的长度:" + len);
            System.out.println("读取的数据:" + new String(data));
            System.out.println(in.read());//空格 -> ascii 32
            System.out.println(in.read());//b -> ascii 98

            //把剩下的逐个儿读完
            int d = -1;
            while ((d = in.read()) != -1) {
                System.out.print((char) d);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           
JavaSE高级开发之I/O流(一)
  • 问题:怎样一下子可以把数据全部读取完?
package com.file;

import java.io.*;

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

        String directory = "D:" + File.separator + "a" + File.separator + "b";
        File file = new File(directory, "test.txt");

        try(InputStream in = new FileInputStream(file)) {

            //采用缓存的方式
            byte[] buff = new byte[1024];

            int len = -1;
            while ((len = in.read(buff)) != -1) {
                System.out.print(new String(buff, 0, len));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           
JavaSE高级开发之I/O流(一)

2.3 字符输出流(Writer)

Writer类的定义结构:
public abstract class Writer implements Appendable, Closeable, Flushable

与OutputStream类相比多了一个Appendable接口。
           

Writer

类提供了一个直接输出字符串的方法:

write(String str)

package com.file;

import java.io.*;

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

        String directory = "D:" + File.separator + "a" + File.separator + "b";
        File file = new File(directory, "test.txt");

        try(Writer writer = new FileWriter(file)) {

            writer.write("Java is best!");
            writer.write("\n");
            writer.write(65);
            writer.write("\n");
            writer.write(new char[]{'A', 'B', 'C'});
            writer.write("\n");
            writer.append("Hello World");
            writer.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           
JavaSE高级开发之I/O流(一)

2.4 字符输入流(Reader)

在上面提到的

Writer

类中提供有方法直接向目标源写入字符串,而在

Reader

类中没有方法可以直接读取字符串类型,这个时候只能通过字符数组进行读取操作。

package com.file;

import java.io.*;

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

        String directory = "D:" + File.separator + "a" + File.separator + "b";
        File file = new File(directory, "test.txt");

        try(Reader reader = new FileReader(file)) {

            System.out.println((char) reader.read());
            System.out.println((char) reader.read());

            char[] buff = new char[10];
            int len = -1;
            while ((len = reader.read(buff)) != -1) {
                System.out.print(new String(buff, 0, len));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           
JavaSE高级开发之I/O流(一)

3. 流的转化

OutputStreamWriter

:将字节输出流变为字符输出流

InputStreamReader

:将字节输入流变为字符输入流

package com.file;

import java.io.*;

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

        File file = new File("D:" + File.separator + "test.txt");

        //字节输出流转换成字符输出流
        try(OutputStream out = new FileOutputStream(file);
            OutputStreamWriter writer = new OutputStreamWriter(out)) {

            writer.write("你好Java!");
            writer.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }

        //字节输入流转换成字符输入流
        try(InputStream in = new FileInputStream(file);
            InputStreamReader reader = new InputStreamReader(in)) {

            char[] buff = new char[1024];
            int len = -1;
            while ((len = reader.read(buff)) != -1) {
                System.out.print(new String(buff, 0, len));
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           
JavaSE高级开发之I/O流(一)