一篇文章带你了解Java I/O流

385 阅读2分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

前言

java的io是实现输入和输出的基础,可以方便的实现数据的输入和输出操作。在java中把不同的输入/输出源(键盘,文件,网络连接等)抽象表述为“流”(stream)。

File类

常用API

访问文件名

getName()、getPath()、getAbsoluteFile()、getAbsolutePath()、getParent()、

renameTo()

修改文件名,要求:1、file1一定存在 2、file2一定不存在

import java.io.File;
​
public class file01 {
    static File file1 = new File("D:\file\test.txt");
    static File file2 = new File("D:\file\test1.txt");
    public static void main(String[] args) {
​
        getName();
    }
    public static void getName(){
        System.out.println(file1.getName());
        System.out.println(file1.getPath());
        System.out.println(file1.getAbsoluteFile());
        System.out.println(file1.getAbsolutePath());
        System.out.println(file1.getParent());
        
        //renameTo修改文件名,要求:1、file1一定存在 2、file2一定不存在
        boolean b = file1.renameTo(file2);
        System.out.println(b);
    }
}

 

文件检测

exists()、canWrite()、canRead()、isFile()、isDirectory()

 

 

public static void exist(){
    System.out.println(file1.exists());
    System.out.println(file1.canWrite());
    System.out.println(file1.canRead());
    System.out.println(file1.isFile());
    System.out.println(file1.isDirectory());
}

获取常规文件信息

lastModified()、length()

lastModified()

查看文件的最后修改时间

// lastModified查看文件的最后修改时间
System.out.println(new Date(file1.lastModified()));
System.out.println(file1.length());

文件操作

createNewFile()、delete()

分别删除、创建file1文件

System.out.println(file1.delete());
if(!file1.exists()){
    System.out.println(file1.createNewFile());
}

目录操作

mkDir()、mkDirs()、list()、listFiles()

  • mkDir是创建一层目录,而mkDirs是如果当上层目录不存在时先创建上层目录在创建本层目录
  • list()获取的数据类型是String类型的,而如果想获取后继续操作可以通listFiles()获取file类型的数据

 

public static void operation() throws IOException {
    System.out.println(file1.delete());
    if(!file1.exists()){
        System.out.println(file1.createNewFile());
    }
    System.out.println(file3.mkdir());
    System.out.println(file4.mkdirs());
​
    System.out.println("-----list 产看文件目录-------");
    String[] strs = file5.list();
    for (int i=0;i< strs.length;i++){
        System.out.println(strs[i]);
    }
​
    System.out.println("-----listFiles 获取的是file类型的-------");
    File[] files = file5.listFiles();
    for (File file : files) {
        System.out.println(file.getName());
    }
}

I/O流

I/O流用于处理设备之间的数据传输

流的分类

按操作数据单位不同分为:字节流(8bit)、字符流(16bit)

按数据流的流向不同分为:输入流、输出流

角色不同分为:节点流、处理流

(抽象基类)字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

节点流

字节流

FileInputStream

其中fis.read()是指一次读取一位字母的ascii码,所以使用时应该通过循环+char转型的方式逐位读取

但是如果用fis.read(byte[] b)的方式,则是将数据存入b中

 

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
​
public class fileStream02 {
    static String fileName = "D:\file\test.txt";
    public static void main(String[] args) throws IOException {
        testFileInputStream();
    }
    public static void testFileInputStream() throws IOException {
        //1、创建一个File类的对象
        File file = new File(fileName);
        //2、创建一个FileInputStream类的对象
        FileInputStream fis = new FileInputStream(file);
        //3、定义要写入数据的数组
        byte[] b = new byte[5];
        //4、读取要写入数据的长度
        int len;
        while((len = fis.read(b))!=-1){
            for (int i=0;i< len;i++){
                System.out.print((char)b[i]);
          }
//            String str = new String(b, 0, len);
//            System.out.print(str);
        }
        fis.close();
    }
}

FileOutputSteam

往文件中写入内容

public static void testFileOutputStream() throws IOException {
    File file = new File(fileName2);
    FileOutputStream fos = new FileOutputStream(file);
    fos.write(("this is Sentiment!").getBytes());
    fos.close();
}

FileInOutputStream

将FileInputStream、FileOutputStream结合,将file1内容复制到file2

public static void testFileInOutputStream() throws IOException {
    File file1 = new File(fileName1);
    File file2 = new File(fileName2);
    FileInputStream fis = new FileInputStream(file1);
    FileOutputStream fos = new FileOutputStream(file2);
    byte[] b = new byte[20];
    int len;
    while ((len=fis.read(b))!=-1){
        fos.write(b,0,len);
    }
    fos.close();
    fis.close();
}

测试代码:

import java.io.*;


public class TestFileInOutputStream02 {
    static String fileName1 = "D:\file\test.txt";
    static String fileName2 = "D:\file\test2.txt";


    public static void main(String[] args) throws IOException {
        //testFileInputStream();
        //testFileOutputStream();
        testFileInOutputStream();
    }
    public static void testFileInOutputStream() throws IOException {
        File file1 = new File(fileName1);
        File file2 = new File(fileName2);
        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);
        byte[] b = new byte[20];
        int len;
        while ((len=fis.read(b))!=-1){
            fos.write(b,0,len);
        }
        fos.close();
        fis.close();
    }
    public static void testFileOutputStream() throws IOException {
        File file = new File(fileName2);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(("this is Sentiment!").getBytes());
        fos.close();
    }


    public static void testFileInputStream() throws IOException {
        //1、创建一个File类的对象
        File file = new File(fileName1);
        //2、创建一个FileInputStream类的对象
        FileInputStream fis = new FileInputStream(file);
        //3、定义要写入数据的数组
        byte[] b = new byte[5];
        //4、读取要写入数据的长度
        int len;
        while((len = fis.read(b))!=-1){
            for (int i=0;i< len;i++){
                System.out.print((char)b[i]);
          }
//            String str = new String(b, 0, len);
//            System.out.print(str);
        }
        fis.close();
    }
}

 

字符流

顾名思义处理字符的,所以只能处理文本文件,对于非文本文件只能用字节流的方式。代码逻辑基本一样,速度比字节流快一些。

FileReader

public static void main(String[] args) throws IOException {
    testFileReader();
}
public static void testFileReader() throws IOException {
    File file = new File(fileNname1);
    FileReader fr = new FileReader(file);
    char[] c = new char[20];
    int len;
    while ((len = fr.read(c))!=-1){
        for (int i=0 ;i<len;i++){
            System.out.print(c[i]);
        }
    }
}

FileReaderWriter

结合,将file1内容复制到file2

public static void testFileReaderAndWriter() throws IOException{
    File file1 = new File(fileNname1);
    File file2 = new File(fileNname2);
    FileReader fr = new FileReader(file1);
    FileWriter fw = new FileWriter(file2);
    char[] c = new char[20];
    int len;
    while ((len= fr.read(c))!=-1){
        fw.write(c,0,len);
    }
    fw.close();
    fr.close();
}

处理流

缓冲流

缓冲流相对于给前边节点流的方式又进行了一层封装,开发中效率更高

下面分别是缓冲流对字节流字符流的处理,就是多了一步new Buffered....

import java.io.*;


public class TestBuffered04 {
    static String fileNname1 = "D:\file\test.txt";
    static String fileNname2 = "D:\file\test2.txt";
    public static void main(String[] args) throws IOException {
        //testBufferInOutputStream();
        testBufferReaderAndWriter();
    }
    public static void testBufferReaderAndWriter() throws IOException{
        File file1 = new File(fileNname1);
        File file2 = new File(fileNname2);
        FileReader fr = new FileReader(file1);
        FileWriter fw = new FileWriter(file2,true);
        BufferedReader br = new BufferedReader(fr);
        BufferedWriter bw = new BufferedWriter(fw);
        char[] c = new char[20];
        int len;
        while ((len = br.read(c))!=-1){
            bw.write(c,0,len);
        }
        bw.close();
        br.close();
    }
    public static void testBufferInOutputStream() throws IOException {
        File file1 = new File(fileNname1);
        File file2 = new File(fileNname2);
        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        byte[] b = new byte[20];
        int len;
        while ((len=bis.read(b))!=-1){
            bos.write(b,0,len);
        }
        bos.close();
        bis.close();
    }
}

转换流

转换流主要用于字符流和字节流的转换:

  • 编码:字符串 —> 字节数组 (OutputStreamWriter)
  • 解码:字节数组 —>字符串 (InputStreamReader)

做个对比就了解了:

左边:当时用BufferedReader()时,其中的数据fr通过FileReader()获取的,也就是字符流

右边:这里的数据fis是通过FileInputStream()获取的,也就是字节流,明显这时候如果再用BufferedReader()无疑是不行的,所以中间就用了一步InputStreamReader()将字节数组转换成字符串,这样就可以继续执行接下来的操作

 

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
​
public class TestOtherStream05 {
​
    public static void main(String[] args) throws IOException {
        //解码:字节数组 —>字符串 (InputStreamReader)
        String fileNname1 = "D:\file\test.txt";
        FileInputStream fis = new FileInputStream(fileNname1);
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        char[] c = new char[20];
        int len;
        while ((len=br.read(c))!=-1){
            for (int i=0;i<len;i++)
                System.out.print(c[i]);
        }
    }
}

结语

通过流的形式允许java程序使用相同的方式来访问不同的输入/输出源。流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两个设备间的传输成为流,流的本质是数据传输。如果对本文感兴趣不妨一键三连支持一下。