IO

IO介绍

以程序为中心,文件、内存、网络连接、数据库、设备将流输入到程序叫输入流。反之将程序的内容输出到文件等叫输出流。
举个例子:你阅读一本书写了一篇观后感,阅读书就是讲只是输入到大脑,写观后感就是将大脑的存储的知识进行输出。

核心类:

说明
File文件类
InputStream字节输入流
OutputStream字节输出流
Reader字符输入流
Writer字符输出流
Closeable关闭流接口
Flushable输出流接口
Serializable序列化接口

File

基本语法

路径的写法

String path= "D:\\Program Files\\JetBrains";
(建议写法)
String path= "D:/Program Files/JetBrains";

构建File对象

public class FileDemo {

    public static void main(String[] args) {
        //1
        String path = "D:/file/csdn-logo.png";
        File file = new File(path);
        System.out.println(file.length());
        //2
        File file1 = new File("D:/file","csdn-logo.png");
        File file2 = new File("D:","file/csdn-logo.png");
        System.out.println(file1.length());
        System.out.println(file2.length());
        //3
        File file3 = new File(new File("D:/file"),"csdn-logo.png");
        File file4 = new File(new File("D:"),"file/csdn-logo.png");
        System.out.println(file3.length());
        System.out.println(file4.length());
        //4
        File file5 = new File("https://csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1");
        System.out.println(file5.length());
    }
}
运行结果:
4990
4990
4990
4990
4990
0

常用文件操作方法

在这里插入图片描述

常用文件夹操作方法

在这里插入图片描述

遍历文件

/**
 * 递归循环遍历文件夹
 */
class FileDemo2{
    public static void main(String[] args) {
        String path = "E:/woody/spring1";
        printFileName(new File(path));
    }

    public static void printFileName(File src){
        if(null == src || !src.exists()){
            return;
        }
        if(!src.isDirectory()){
            System.out.println(src.getName());
        }else{
            File[] files = src.listFiles();

            for (File f: files) {
                printFileName(f);
            }
        }
    }
}

文件编码

字符集

各种字符集实际上就是不同的字典。
编码:字符转换成字节的过程
解码:字节转换成字符的过程
在这里插入图片描述

乱码原因

  • 字节数组给的不够,比如“你好”,使用utf-8编码后的字节长度是6,解码的时候入参长度传5,那么“好”字就会乱码
  • 使用的字符集不一致,比如“你好”,使用utf-8编码后的字节长度是6,解码的时候使用UTF-16LE,因为UTF-16LE是定长2字节的,所以解码的时候会解析三次导致乱码。

IO流

整体概况

在这里插入图片描述

关键的四个类

在这里插入图片描述
PS:音频、视频、Excel等只能使用字节流。

Closeable接口

inputstream、outputstream类实现了Closeable接口,Java操作文件的时候不能直接操作文件,而是通过操作系统进一步操作文件的,此处的closeable接口不是Java直接释放资源,而是通知操作系统可以释放资源,真正的释放资源是操作系统执行的。

Flushable接口

outputstream类实现了flushable接口,写文件时候操作系统的计数器有一定的规则,比如达到8k才输出出去,如果没有达到则注入到内存中,所以flushable能避免数据注入到内存中,当然close的时候也是会强制刷新的。

字节流

在这里插入图片描述

InputStream操作

public class IODemo {
    public static void main(String[] args) {
        //1、创建源 abc.txt 里面的内容为sex
        File src = new File("E:/woody/abc.txt");
        //2、选择流
        try {
            InputStream is = new FileInputStream(src);

            //3、操作
            int data1 = is.read();
            int data2 = is.read();
            int data3 = is.read();
            int data4 = is.read();//不是数据,文件的末尾返回-1
            System.out.println((char)data1);
            System.out.println((char)data2);
            System.out.println((char)data3);
            System.out.println(data4);
            //4、释放
            is.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
输出结果:
s
e
x
-1
class IODemo1 {
    public static void main(String[] args) {
        //1、创建源 abc.txt 里面的内容为sex
        File src = new File("E:/woody/abc.txt");
        //2、选择流
        InputStream is = null;
        try {
            is = new FileInputStream(src);

            //3、操作
            int temp;
            while ((temp = is.read()) != -1){
                System.out.println((char)temp);
            }
            //4、释放
            is.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(null != is){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
输出结果:
s
e
x

通过读取数据到缓冲数组方式:

//3、操作
 byte[] flush = new byte[1024];
 int len;
 while ((len = is.read(flush)) != -1){
     System.out.println(new String(flush,0,len));
 }

OutputStream操作

class IODemo3 {
    public static void main(String[] args) {
        //1、创建源
        File dest = new File("E:/woody/dest.txt");
        
        OutputStream os = null;
        try {
        	//2、选择流
            os = new FileOutputStream(dest);
			//os = new FileOutputStream(dest,true);//追加模式,在文本后面继续追加内容,默认为false
            
            String msg = "i love you";
            byte[] bytes = msg.getBytes();
			//3、操作
            os.write(bytes,0 , bytes.length);
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4、释放资源
            if(null != os){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

字符流

在这里插入图片描述

FileReader

通过字符的方式读取文件,仅适合字符文件。

/**
 * 字符输入流
 */
class IODemo4 {
    public static void main(String[] args) {
        //1、创建源 abc.txt 里面的内容为sex
        File src = new File("E:/woody/abc.txt");
        //2、选择流
        Reader reader = null;
        try {
            reader = new FileReader(src);

            //3、操作
            char[] flush = new char[1024];
            int len;
            while ((len = reader.read(flush)) != -1){
                System.out.println(new String(flush,0,len));
            }
            //4、释放
            reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(null != reader){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
输出结果:sex

FileWriter

通过自己的方式写出或追加到文件中,仅适合字符文件。

/**
 * 字符输出流
 */
class IODemo5 {
    public static void main(String[] args) {
        //1、创建源
        File dest = new File("E:/woody/dest.txt");

        Writer writer = null;
        try {
            //2、选择流
            writer = new FileWriter(dest);

            String msg = "i love 妈妈啊";
            String msg1 = "i love 爸爸啊";

            //3、操作(方法一)
            //char[] bytes = msg.toCharArray();
            //writer.write(bytes,0 , bytes.length);
            //3、操作(方法二)
            //writer.write(msg);
            //3、操作(方法三)
            writer.append(msg).append(msg1);
            writer.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4、释放资源
            if(null != writer){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

字节数组流

字节数组流与前面提到的FileXXX的区别是,FileXXX的是操作的是存储硬盘中的,需要通过操作系统来操作文件,释放资源是通知操作系统进行释放。而字节数组流操作流是存放在内存中的,因此释放是由jvm 的垃圾回收操作的,因此不需要手动释放。

ByteArrayInputStream

/**
 * 字节数组输入流
 */
class IODemo6 {
    public static void main(String[] args) {
        //1、创建源
        byte[] src = "i love you".getBytes();

        InputStream is = null;
        try {
            //2、选择流
            is = new ByteArrayInputStream(src);

            //3、操作
            byte[] flush = new byte[1024];
            int len = -1;
            while((len =  is.read(flush,0,flush.length)) != -1){
                System.out.println(new String(flush));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
输出结果:i love you

ByteArrayOutputStream

/**
 * 字节数组输出流
 */
class IODemo7 {
    public static void main(String[] args) {
        ByteArrayOutputStream baos = null;
        try {
            //2、选择流
            baos = new ByteArrayOutputStream();

            String msg = "i love you";
            byte[] datas = msg.getBytes();
            //3、操作
            baos.write(datas,0 , datas.length);
            baos.flush();
            //4、获取数据
            System.out.println(baos.toByteArray());
            System.out.println(baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
输出结果:
[B@610455d6
i love you

缓冲流

增加了缓存机制,使用的是装饰模式实现的。

  • 目的是为了提升性能
  • 底层一定是节点流
  • 关闭的时候由里到外关闭,实际上装饰流在关闭的时候会自动关闭内部的节点流
  • 默认缓存8K

字节缓冲流

BufferedInputStream
BufferedOutbputStream
/**
 - 字节装饰输入流
 */
class IODemo8 {
    public static void main(String[] args) {
        //1、创建源 abc.txt 里面的内容为sex
        File src = new File("E:/woody/abc.txt");
        //2、选择流
        InputStream is = null;
        try {
        	//关键
            is = new BufferedInputStream(new FileInputStream(src));

            //3、操作
            byte[] flush = new byte[1024];
            int len;
            while ((len = is.read(flush)) != -1){
                System.out.println(new String(flush,0,len));
            }
            //4、释放
            is.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(null != is){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

字符缓冲流

BufferedReader

新增了readLine()逐行读取方法。

BufferedWriter

新增了newLine()方法
BufferedReader示例:

/**
 * 字符缓冲输入流
 */
class IODemo9 {
    public static void main(String[] args) {
        //1、创建源 abc.txt 里面的内容为sex
        File src = new File("E:/woody/abc.txt");
        //2、选择流
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(src));

            //3、操作
            String line = null;

            while ((line = reader.readLine()) != null){
                System.out.println(line);
            }
            //4、释放
            reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(null != reader){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

BufferedWriter实例:

/**
 * 字符缓冲输出流
 */
class IODemo10 {
    public static void main(String[] args) {
        //1、创建源
        File dest = new File("E:/woody/dest.txt");

        BufferedWriter writer = null;
        try {
            //2、选择流
            writer = new BufferedWriter(new FileWriter(dest));

            String msg = "i love 妈妈啊";
            String msg1 = "i love 爸爸啊";

            writer.append(msg);
            writer.newLine();
            writer.append(msg1);
            writer.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4、释放资源
            if(null != writer){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

转换流

  • 以字符流的方式操作字节流
  • 指定字符集

InputStreamReader

OutPutStreamWriter

转换流示例:

/**
 * 转换流
 */
class IODemo11 {

    public static void main(String[] args) {

        try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

            String line = "";
            while(!line.equals("exit")){
                line = reader.readLine();
                writer.write(line);
                writer.newLine();
                writer.flush();
            }
        }catch(IOException e){
            e.printStackTrace();
        }

    }
}

转换流指定字符集示例:爬取网页保存为文件

class IODemo12 {

    public static void main(String[] args) {
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try{
            reader = new BufferedReader(new InputStreamReader(new URL("https://www.baidu.com/").openStream(),"utf-8"));
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:/woody/baidu.html"),"utf-8"));
            String msg;
            while((msg = reader.readLine()) != null){
                writer.write(msg);
                writer.newLine();
                writer.flush();
            }
        }catch (MalformedURLException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(writer != null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

数据流

保留了数据类型,方便后期的处理,读写顺序必须保持一致

DataInputStream

DataOutputStream

对象流

必须实现序列化接口的才能用

ObjectInputStream

ObjectOutputStream

打印流

PrintStream

System.out.print就是一个打印流

CommonsIo

常用方法

FileUtils.sizeOf()

计算文件或者文件夹的大小

long len = FileUtils.sizeOf(new File("E:/woody/baidu.html"));

FileUtils.listFiles()

遍历子孙集,第二个参数过滤文件,比如可以设置后缀名或者非空等等,第三个参数控制目录

Collection<File> files = FileUtils.listFiles(new File("E:/woody/"), EmptyFileFilter.NOT_EMPTY, DirectoryFileFilter.INSTANCE);
        for (File file:files) {
            System.out.println(file.getAbsoluteFile());
        }

FileUtils.readFileToString

读取文件

String msg = FileUtils.readFileToString(new Filee("E:/woody/baidu.html"),"utf-8");

FileUtils.readLines

//逐行读取
        List<String> msgs = null;
        try {
            msgs = FileUtils.readLines(new File("E:/woody/baidu.html"),"utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        for(String str :msgs){
            System.out.println(str);
        }

FileUtils.lineIterator

 //迭代器逐行读取
        try {
            LineIterator it = FileUtils.lineIterator(new File("E:/woody/baidu.html"),"utf-8");
            while (it.hasNext()){
                System.out.println(it.nextLine());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

写文件

 //写文件,最后一个参数表示是否追加
        try {
            FileUtils.write(new File("E:/woody/commonsio.txt"),"生命诚可贵\n","utf-8",true);
            FileUtils.writeStringToFile(new File("E:/woody/commonsio.txt"),"爱情价更高\n","utf-8",true);
            FileUtils.writeByteArrayToFile(new File("E:/woody/commonsio.txt"),"若为自由故\n".getBytes("utf-8"),true);

            List<String> list = new ArrayList<String>();
            list.add("窗前明月光\n");
            list.add("疑是地上霜\n");
            list.add("举头望明月\n");
            FileUtils.writeLines(new File("E:/woody/commonsio.txt"),list,",",true);
        } catch (IOException e) {
            e.printStackTrace();
        }

在这里插入图片描述

文件拷贝

//拷贝文件
 try {
     //拷贝文件
     FileUtils.copyFile(new File("E:/woody/commonsio.txt"),new File("E:/woody/commonsio-copy.txt"));
     //拷贝文件至目录下
     FileUtils.copyToDirectory(new File("E:/woody/commonsio.txt"),new File("E:/woody/sub/"));
     //拷贝目录至目录下
     FileUtils.copyDirectoryToDirectory(new File("E:/woody/"),new File("E:/woody/sub/"));
     //拷贝目录
     FileUtils.copyDirectoryToDirectory(new File("E:/woody/"),new File("E:/woody2"));
     //拷贝URL内容
     String url = "https://csdnimg.cn/cdn/content-toolbar/csdn-logo.png";
     FileUtils.copyURLToFile(new URL(url),new File("E:/woody/csdn-logo.png"));
     //拷贝URL文本
     String datas = IOUtils.toString(new URL("https://www.baidu.com"),"utf-8");
 } catch (IOException e) {
     e.printStackTrace();
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值