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

java.io包里的核心组成就是五个类(FileOutputStreamInputStreamWriterReader)。

1. File文件操作类

1.1 文件操作

Java.io包之中,File类是唯一一个与文件本身操作(创建、删除、取得信息等)有关的程序类。

  • File类中关于文件有如下方法::
    ① 设置文件路径:File(String pathname)
    ② 设置父路径和子路径:File(String parent, String child)
    ③ 判断文件是否存在:exists()
    ④ 新建文件:createNewFile() ,只是创建文件本身,对于其内容并不做处理!
    ⑤ 删除文件:delete()

对于文件路径有以下要注意的点:
Windows平台下使用的是 反斜杠,而在Linux系统下使用的是 “/” 。所以在使用路径分隔符时都会采用File类的一个常量separator来描述。它会根据平台而选定使用哪种分隔符。

package www.bittech.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 www.bittech.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 www.bittech.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());

                }
            }
        }
    }
}

在这里插入图片描述

2. 字节流与字符流

java.io包中,流分为两种:字节流(InputStreamOutputStream)和字符流(ReaderWriter)。又或者分为输入流(InputStreamReader)和输出流(OutputStreamWriter)。
在这里插入图片描述
在这里插入图片描述
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 www.bittech.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();
                }
            }
        }
    }
}

在这里插入图片描述

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 www.bittech.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();
        }
    }
}

在这里插入图片描述

  • 问题:怎样一下子可以把数据全部读取完?
package www.bittech.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();
        }
    }
}

在这里插入图片描述

2.3 字符输出流(Writer)

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

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

Writer类提供了一个直接输出字符串的方法:write(String str)

package www.bittech.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();
        }
    }
}

在这里插入图片描述

2.4 字符输入流(Reader)

在上面提到的Writer类中提供有方法直接向目标源写入字符串,而在Reader类中没有方法可以直接读取字符串类型,这个时候只能通过字符数组进行读取操作。

package www.bittech.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();
        }
    }
}

在这里插入图片描述

3. 流的转化

OutputStreamWriter:将字节输出流变为字符输出流
InputStreamReader:将字节输入流变为字符输入流

package www.bittech.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();
        }
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43508801/article/details/89140141