java IO

IO

I: Input
O:Output

通过IO可以完成硬盘文件的读和写。

IO流的分类:

1、流的方向分类

(1)往内存中去读 - 输入;

(2)从内存中出来,写 - 输出。

2、另一种方式是按照读取数据方式不同进行分类

(1)按字节读取

有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位,这种流是万能的,什么类型的文件都可以读取,包括:文本文件、图片、声音文件、视频文件等等··· ···

(2)按字符读取

有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,他不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都读取不了。

IO四大家族

java.io.InputStream    字节输入流
java.io.OutputStream    字节输出流

java.io.Reader   字符输入流
java.ioWriter    字符输出流

注意:在java中只要 "类名" 以stream 结尾 的都是字节流。以 "Reader/Writer" 结尾的都是字符流。

所有流都实现了 java.io.Closeable接口,都是可以关闭的,都有close() 方法。
流毕竟是一个管道,是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费(占用)很多资源。

所有流都实现了java.io.Flushable接口,都是可刷新的,都有flush() 方法。
输出流在最终输出之后,一定要记得flush(),刷新一下,这个刷新表示将通道、管道当中剩余的为输出的数据强行输出完毕(清空管道),刷新的作用就是清空管道。

注意:如果没有flush() 可能会丢失数据。

几个常用的流:

// 文件专属
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;

// 转换流(将字节流转化为字符流)
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

// 缓冲流专属:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;

// 数据专属流:
import java.io.DataInputStream;
import java.io.DataOutputStream;

// 标准输出流
import java.io.PrintStream;
import java.io.PrintWriter;

// 对象专属
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

以FileInputStream为例

从硬盘到内存(例:上传图片)

1、new FileInputStream(path) 创建流

public class IOStream {
    public static void main(String[] args) {
        String imagePath = null;
        FileInputStream fileInputStream = null;
        try {
            // 获取图片路径
            imagePath = ResourceUtils.getURL("classpath:").getPath()+"static/image/0710.jpg";
            System.out.println("imagePath: "+imagePath);
            // 创建一个流()
            fileInputStream = new FileInputStream(imagePath);
            System.out.println("fileInputStream: "+fileInputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 确保流的存在,在关闭它,否则报:空指针异常
            if(fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2、fileInputStream.read() 读取流

读取流,一次读一个字节,读到最后如果没读到数据会返回-1。

注意:一次读取一个字节,效率很低。

public class IOStream {
    public static void main(String[] args) {
            // 获取图片路径
            String imagePath = ResourceUtils.getURL("classpath:").getPath()+"static/image/0710.jpg";
            System.out.println("imagePath: "+imagePath);
            // 创建一个流()
            FileInputStream fileInputStream = new FileInputStream(imagePath);

            while(fileInputStream.read() != -1) {
                System.out.println(fileInputStream.read());
            }
    }
}

3、(重点)Int byteCount = fileInputStream.read( Byte[ ] byte )

往byte数组中读,一次读取 byte.length个字节。减少磁盘与内存之间的交互,提高程序的执行效率

返回值是:每次读到的字节数量,最后读取不到返回-1。

public class IOStream {
    public static void main(String[] args) {
        String imagePath = null;
        FileInputStream fileInputStream = null;
        try {
            // 获取路径
            imagePath = ResourceUtils.getURL("classpath:").getPath()+"static/image/0710.jpg";
            System.out.println("imagePath: "+imagePath);
            // 创建一个流()
            fileInputStream = new FileInputStream(imagePath);
            // 创建一个长度为100 的字节数组,每次会往字节数组中放入 10个字节的图片数据。
            byte[] byteArray = new byte[100];
            // 返回的是每一次读到的字节数量
             int byteCount = 0;
            while((byteCount = fileInputStream.read(byteArray)) != -1) {
                // 把字节数组转化为字符串,参数二:开始转化的字节索引位,参数三:要解码的字节数
                System.out.println(new String(byteArray, 0, byteCount));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 确保流的存在,在关闭它,否则报:空指针异常
            if(fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4、fileInputStream.available( )

获取剩余未读到的字节数量,可以利用这个方法计算要读的资源的字节大小n,然后创建 一个 n大小的字节数组,这样就不需要要循环来读取了。

注意:这种方式不适合大文件,因为byte数组不能太大,且 fileInputStream.available( ) 返回的是int类型的!

public class IOStream {
    public static void main(String[] args) {
        String imagePath = null;
        FileInputStream fileInputStream = null;
        try {
            // 获取路径
            imagePath = ResourceUtils.getURL("classpath:").getPath()+"static/test.txt";
            fileInputStream = new FileInputStream(imagePath);
            // 获取未读到的字节数量
            int unreadByteCount = fileInputStream.available();
            // 创建一个字节数组,大小就是资源的字节大小,这样就不需要每次循环读取了
            byte[] bytes = new byte[unreadByteCount];
            fileInputStream.read(bytes);
            String byteString = new String(bytes);
            System.out.println(byteString);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 确保流的存在,在关闭它,否则报:空指针异常
            if(fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

小例子:

获取图片base64编码:

// 获取图片base64
// param-> imageFile 图片真实的路径 (例:c:\d\1.jpg)
private static byte[] getbase64Url(String imageFile) {
    InputStream inputStream = null;
    byte[] data = null;
    try {
        // 转输入流
        inputStream = new FileInputStream(imageFile);
        // 定义字节数组大小 inputStream.available()获取流大小
        data = new byte[inputStream.available()];
        // 图片流读到数组中去,从磁盘向内存中读
        inputStream.read(data);
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return data;
}


 

以FileOutputStream为例

从内存到硬盘。

1、new FileInputStream(path) 创建写入流(文件不存在:会创建一个文件,存在:会先清空源文件内容,然后在重新写入内容)

文件不存在,创建新文件:

向static文件夹下写入1.txt

public class IOStream {
    public static void main(String[] args) {
        FileOutputStream fileOutputStream = null;
        try {
            String filePath = ResourceUtils.getURL("classpath:").getPath()+"static/1.txt";
            fileOutputStream = new FileOutputStream(filePath);
            // 开始写。
            byte[] bytes = {97, 98, 99, 120};
            fileOutputStream.write(bytes);
            // 写入后要刷新
            fileOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileOutputStream != null) {
                    fileOutputStream.close()
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

注意:如果一个文件夹中没有任何文件(空文件夹),打包时会过滤掉,不会打包!所以写入的时候,不能写入一个空文件夹,否则会报:文件找不到!

2、源文件存在,在文件末尾写入内容

String filePath = ResourceUtils.getURL("classpath:").getPath()+"static/1.txt";
fileOutputStream = new FileOutputStream(filePath, true);

3、把字符串写入文件

public class fileStream {
    public static void main(String[] args) {
        FileOutputStream fileOutputStream = null;
        try {
            String filePath = ResourceUtils.getURL("classpath:").getPath()+"static/1.txt";
            fileOutputStream = new FileOutputStream(filePath, true);
            // 把字符串写入文件。
            String say = "大家好,我来自火星!";
            // 字符串转byte数组
            byte[] bytes = say.getBytes();
            // 开始写。
            fileOutputStream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileOutputStream != null) {
                    // 输出后要刷新
                    fileOutputStream.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 4、小例子:拷贝一个文件

// 文件复制 - 把指定文件复制到指定目录下文件。
public class fileStream {
    public static void main(String[] args) {
        FileOutputStream outStream  = null;
        FileInputStream inputStream = null;
        try {
            // 指定一个复制的目录文件
            String path = ResourceUtils.getURL("classpath:").getPath()+"static/2.jpg";
            inputStream = new FileInputStream("C:\\Users\\l'x'c\\Desktop\\1.jpg");
            outStream = new FileOutputStream(path);

            //边读边写
            byte[] bytes = new byte[10 * 1024]; // 每次读10kb
            int byteCount = 0;
            while((byteCount = inputStream.read(bytes)) != -1) {
                // 写入指定数量
                outStream.write(bytes, 0, byteCount);
            }
            outStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outStream != null) {
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

PrintStream

标准输出流,使用这个流我们可以把原本输出到控制台中的信息,输出到文件中。

// 文件复制 - 把指定文件复制到指定目录下文件。
public class fileStream {
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String fileName = simpleDateFormat.format(date);
        String dest = null;
        try {
            dest = ResourceUtils.getURL("classpath:").getPath()+"static/"+simpleDateFormat.format(date)+".log";
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            FileOutputStream fileStream = new FileOutputStream(dest, true);
            //标准输出流 PrintStream参数是一个 OutputStream,我们可以用 FileOutputStream,
            // 因为 FileOutputStream继承OutputStream
            // 创建一个标准输出流,输出到static文件夹下的 log文件中。
            PrintStream printStream = new PrintStream(fileStream);
            // 改变输出流的方向
            System.setOut(printStream);
            // 输出的信息
            printStream.println(fileName+":大家好,我来自火星!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

对象专属流

待记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值