一、I/O流体系

1. 字节流

InputStream
OnputStream

1)简单使用FileOutputStream

import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamTest {public static void main(String[] args) throws IOException {/*1.创建字节流输出对象构造函数入参可以是字符串表示文件路径,或File对象如果文件不存在会新建一个文件,但前提是父路径存在如果文件已存在,则会清空内容2.写数据write方法入参是int类型,实际上写入的内容是这个整数在ASCII码表上对应的字符3.释放资源每次使用完流都需要释放资源,否则就会一直占用
*/FileOutputStream fos = new FileOutputStream("D:\\studyspace\\myio\\a.txt");fos.write(97);fos.close();}
}

2 )三种写入数据的方式

//        1.一次写一个字节的数据fos.write(97);
//        2.一次写一个字节数组的数据byte[] bt = new byte[]{98,99,100};fos.write(bt);
//        3.一次写一个字节数组的部分数据  参数:字节数组,起始位置的下标,需要写入的长度fos.write(bt,1,2);

3 )换行和续写

/*换行写:写入一个换行符Windows: \r\nLinux:   \nMac:     \r在Windows中Java对回车进行了优化虽然完整的是\r\n 但是我们写其中一个\r或者\nJava也可以实现换行,底层会自动补全续写: 构造函数的第二个参数默认是false,不续写清空文件内容可以手动传入true
*/FileOutputStream fos = new FileOutputStream("D:\\studyspace\\myio\\a.txt",true);String s1 = "wodetianwozenmenameshuai";byte[] bytes1 = s1.getBytes();fos.write(bytes1);String s2 = "\r\n";fos.write(s2.getBytes());String s3 = "666";fos.write(s3.getBytes());fos.close();

4)简单使用FileIutputStream

import java.io.FileInputStream;
import java.io.IOException;
public class ByteStreamTest {public static void main(String[] args) throws IOException {/** 如果文件不存在,直接报错* 一次read读取一个字节,读出来的数据就是在ASCII上对应的数字* 读到文件末尾,read方法返回-1* */FileInputStream fis = new FileInputStream("D:\\studyspace\\myio\\a.txt");int b1 = fis.read();System.out.println((char) b1);int b2 = fis.read();System.out.println((char) b2);int b3 = fis.read();System.out.println((char) b3);int b4 = fis.read();System.out.println((char) b4);fis.close();}
}

5)FileIutputStream 循环读取

        FileInputStream fis = new FileInputStream("D:\\studyspace\\myio\\a.txt");int b;while ((b = fis.read()) != -1) {System.out.println((char) b);}fis.close();

6)简单文件拷贝

//        小文件拷贝,缺点:速度慢FileInputStream fis = new FileInputStream("D:\\studyspace\\myio\\a.txt");FileOutputStream fos = new FileOutputStream("D:\\studyspace\\myio\\b.txt");
//        思路:读一个,写一个,缺点:速度慢int b;while ((b = fis.read()) != -1) {fos.write(b);}//        通常最先打开的,最后关闭fos.close();fis.close();
//        一次读取多个字节FileInputStream fis = new FileInputStream("D:\\studyspace\\myio\\a.txt");
//        入参的字节数组多大,一次就会读取多少个字节并写入到字节数组中byte[] bytes = new byte[2];
//        返回值为本次读取的长度int len1 = fis.read(bytes);
//        表示从什么位置开始  读取多长的数据 转化为字符串String s1 = new String(bytes, 0, len1);System.out.println(s1);//        多次读取则覆盖原来位置的数据int len2 = fis.read(bytes);String s2 = new String(bytes, 0, len2);System.out.println(s2);int len3 = fis.read(bytes);String s3 = new String(bytes, 0, len3);System.out.println(s3);fis.close();
        long start = System.currentTimeMillis();
//        大文件拷贝FileInputStream fis = new FileInputStream("D:\\yxh\\奇妙能力歌.mp3");FileOutputStream fos = new FileOutputStream("D:\\studyspace\\myio\\奇妙能力歌.mp3");
//        一次读取1M的数据byte[] bytes = new byte[1024*1024];int len;while ((len = fis.read(bytes)) != -1) {//            读到多少数据就写多少数据fos.write(bytes,0,len);}fos.close();fis.close();long end = System.currentTimeMillis();System.out.println(end - start);
        long start = System.currentTimeMillis();
//      jdk1.7开始  实现了 AutoCloseable接口的 流,可以在  try(){} 这种写法中自动关闭try (FileInputStream fis = new FileInputStream("D:\\yxh\\奇妙能力歌.mp3");FileOutputStream fos = new FileOutputStream("D:\\studyspace\\myio\\奇妙能力歌.mp3");){//        一次读取1M的数据byte[] bytes = new byte[1024*1024];int len;while ((len = fis.read(bytes)) != -1) {//            读到多少数据就写多少数据fos.write(bytes,0,len);}} catch (IOException e) {e.printStackTrace();}finally {System.out.println("拷贝结束拉");}long end = System.currentTimeMillis();System.out.println(end - start);

2. 字符流

Reader
Writer

FileReader

import java.io.FileReader;
import java.io.IOException;
public class CharStreamTest {public static void main(String[] args) throws IOException {/** 字符流底层也是字节流,默认一次也是读取一个字节,不同的是会根据不同的编码读取* 如果遇到中文一次就会读取多个字节  GBK一次读取两个字节,UTF-8一次读取三个字节* */FileReader fr = new FileReader("D:\\studyspace\\myio\\a.txt");int b ;while ((b = fr.read()) != -1) {System.out.print((char) b);}fr.close();}
}
     //批量读取字符FileReader fr = new FileReader("D:\\studyspace\\myio\\a.txt");int len;char[] chars = new char[2];while ((len = fr.read(chars)) != -1) {System.out.println(new String(chars,0,len));}fr.close();

FileWriter

        FileWriter fw = new FileWriter("D:\\studyspace\\myio\\a.txt");
//        1.字符对应的编码值fw.write(25105);
//        2.直接写入字符串String str= "你好牛啊?";fw.write(str);
//        3.写入字符数组char[] chars = new char[]{'你','愁','啥','?'};fw.write(chars);
//        4.写入字符数组的一部分fw.write(chars,1,3);
//        5.写入字符串的一部分fw.write(str,2,3);fw.close();

字符流原理解析

① 创建字符输入流对象底层:关联文件,并创建缓冲区(长度为8192的字节数据)
② 读取数据底层:1. 判断缓冲区中是否有数据可以读取2. 缓冲区中没有数据:就从文件中获取,装到缓冲区中,尽量每次都装满缓冲区如果文件中也没数据了,就返回-13. 缓冲区中有数据:就从缓冲区中读取空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解吗并转成十进制返回有参的read方法:把读取字节、解码、强转三步合并,强转之后的字符放入字符数组中
Writer同理:字符会先写入到缓冲区中,当缓冲区满了、手动调用flush方法、调用close方法关闭字符流 时
才会把当前缓冲区中的数据写入到文件中

文件夹拷贝Demo

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class CopyFileTest {public static void main(String[] args) throws IOException {copydir(new File("D:\\adir"),new File("D:\\bdir"));}/*** @param src 源文件夹* @param tag 目标文件夹* @throws Exception*/private static void copydir(File src, File tag) throws IOException {tag.mkdir();File[] files = src.listFiles();for (File file : files) {if (file.isFile()) {FileInputStream fis = new FileInputStream(file);FileOutputStream fos = new FileOutputStream(new File(tag, file.getName()));byte[] bytes = new byte[1024];int len;while ((len = fis.read(bytes)) != -1) {fos.write(bytes,0,len);}fos.close();fis.close();} else {copydir(file,new File(tag,file.getName()));}}}
}

文件加密Demo

/*^ 异或运算1. boolean ^ boolean  相同为false 不同为true2. 数字 异或 100 ^ 1011001000001010---------11011101 * 2^6 + 1 * 2^5 + 0 + 1 * 2^3 + 1 * 2^2 + 1 * 2 + 0 = 64 + 32 + 8 + 4 + 2 = 110100 ^ 10 = 110110 ^ 10 = 100所以可以通过异或运算加解密* */FileInputStream fis = new FileInputStream("D:\\studyspace\\myio\\a.txt");FileOutputStream fos = new FileOutputStream("D:\\studyspace\\myio\\b.txt");int b;while ((b = fis.read()) != -1) {fos.write(b ^ 10);}fos.close();fis.close();

3. 字节缓冲流

BufferedInputStream
BufferedOutputStream

构造函数

// 默认创建一个大小为 8192的缓冲区private static int DEFAULT_BUFFER_SIZE = 8192;public BufferedInputStream(InputStream in, int size) {super(in);if (size <= 0) {throw new IllegalArgumentException("Buffer size <= 0");}buf = new byte[size];}

单字节读写和字节数组读写

     BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\studyspace\\myio\\a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\studyspace\\myio\\b.txt"));int b;while ((b = bis.read())!=-1) {bos.write(b);}bos.close();bis.close();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\studyspace\\myio\\a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\studyspace\\myio\\b.txt"));int len;byte[] bytes = new byte[1024];while ((len = bis.read(bytes))!=-1) {bos.write(bytes,0,len);}bos.close();bis.close();

3. 字符缓冲流

字符流本身就有缓冲流再次封装对性能的提升不大,但是有了两个特别好用的方法 readLinenewLine

BufferedReader
BufferedWriter
     BufferedReader br = new BufferedReader(new FileReader("D:\\studyspace\\myio\\a.txt"));/** readLine方法在读取的时候,一次读取一整行,遇到回车换行结束* 但是读取的内容不包含换行符* *//*String line1 = br.readLine();System.out.println(line1);String line2 = br.readLine();System.out.println(line2);*/String line;while ((line = br.readLine()) != null) {System.out.println(line);}br.close();
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\studyspace\\myio\\a.txt"));bw.write("我结婚的时候,你一定要来哦~");
//        这是一个跨平台的换行操作,根据操作系统的不同,写入对应系统的换行符bw.newLine();bw.write("婚礼没有新娘我会很尴尬……");bw.newLine();bw.close();
 /** 将b.txt中乱序的文本排序后写入a.txt* */BufferedReader br = new BufferedReader(new FileReader("D:\\studyspace\\myio\\b.txt"));String line;TreeMap<Integer,String> tm = new TreeMap<>();while ((line = br.readLine()) != null) {tm.put(Integer.parseInt(line.split("\\.")[0]),line);}BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\studyspace\\myio\\a.txt"));for (String value : tm.values()) {bw.write(value);bw.newLine();}bw.close();br.close();

4. 转换流

InputStreamReader
OutputStreamWriter
//        利用转换流按照指定编码读取
//        jdk11 这种写法就被替代了,参数 charset 被集成到了字类 FileReader上
//        new FileReader("D:\\studyspace\\myio\\ist.txt", Charset.forName("GBK"))InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\studyspace\\myio\\ist.txt"), "GBK");int b;while ((b = isr.read()) != -1) {System.out.print((char) b);}isr.close();OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\studyspace\\myio\\isr.txt"), "GBK");osw.write("呵呵");osw.close();

5. 序列化流

ObjectInputStream
ObjectOutputStream
     Student student = new Student();student.setAge(18);student.setName("张三");student.setAddress("北京");ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\studyspace\\myio\\oos.txt"));oos.writeObject(student);oos.close();ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\studyspace\\myio\\oos.txt"));Student object = (Student) ois.readObject();System.out.println(object);ois.close();
import java.io.Serializable;public class Student implements Serializable {private static final long serialVersionUID = 6768132401505607054L;private int age;private String name;private transient String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +", address='" + address + '\'' +'}';}
}

Serializable标志性接口,当类实现了此接口,就表示此类的对象需要序列化
serialVersionUID相当于类的版本号,当没指定该属性时,Java会自动根据类的属性方法等计算出一个值,当类的属性方法修改后,计算出来的值就可能和之前的不一样,会导致反序列化失败,所以通常会手动指定该属性的值,并且非特殊情况不会轻易修改该值

Exception in thread "main" java.io.InvalidClassException: Student; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 985628350043525245at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1885)at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)at ObjectStreamTest.main(ObjectStreamTest.java:21)Process finished with exit code 1

可以在idea中配置自动生成serialVersionUID,当类没有指定该属性时就会进行提示



transient当需要某些属性不被序列化时,可以使用该关键字修饰属性

6. 打印流

打印流只有输出流没有输入流

//        字节打印流,没有缓冲区,自动刷新开启与否没有影响PrintStream ps = new PrintStream("D:\\studyspace\\myio\\ps.txt");// 原样输出  自动刷新  自动换黄ps.println(97);ps.print(true);ps.println();
//        占位符,和C语言类似ps.printf("%s爱上了%s","阿珍","阿强");ps.close();
//        字符打印流,有缓冲区,需要打开 自动刷新PrintWriter pw = new PrintWriter(new FileWriter("D:\\studyspace\\myio\\pw.txt"),true);pw.println(97);pw.print(true);pw.println();pw.printf("%s爱上了%s","阿珍","阿强");pw.close();

7. 压缩流

Java中只能识别zip格式的压缩包

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;public class ZipStreamTest {public static void main(String[] args) throws IOException {File src = new File("D:\\adir.zip");File dest = new File("D:\\adir");unzip(src,dest);}private static void unzip(File src,File dest) throws IOException {//        解压的本质:把压缩包里的每一个文件或文件夹读取出来,按层级拷贝到目的地当中//        创建一个解压缩流来读取压缩包中的数据ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
//        获取压缩包中的ZipEntry对象ZipEntry entry;while ((entry = zip.getNextEntry()) != null) {System.out.println(entry);if (entry.isDirectory()) {new File(dest,entry.toString()).mkdir();} else {int b;FileOutputStream fos = new FileOutputStream(new File(dest, entry.toString()));while ((b = zip.read()) != -1) {fos.write(b);}fos.close();zip.closeEntry();}}zip.close();}
}


压缩单个文件

   public static void main(String[] args) throws IOException {File src = new File("D:\\a.txt");File dest = new File("D:\\");tozip(src,dest);}//    压缩单个文件private static void tozip(File src,File dest) throws IOException {//        创建压缩流关联压缩文件ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest, "a.zip")));
//        创建ZipEntry,标识压缩包里的一个文件或文件夹ZipEntry entry = new ZipEntry("a.txt");
//        把entry放入到压缩包中zos.putNextEntry(entry);
//        把src中文件的数据写入到压缩包里FileInputStream fis = new FileInputStream(src);int b;while ((b = fis.read()) != -1) {zos.write(b);}zos.closeEntry();zos.close();}

压缩文件夹

   public static void main(String[] args) throws IOException {File src = new File("D:\\adir");ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(src.getParent(), src.getName() + ".zip")));tozip(src,zos,src.getName());zos.close();}/*** 获取src里的每一个文件,变成 ZipEntry放入压缩包* @param src 数据源* @param zos 压缩流对象* @param name 压缩包内的路径* @throws IOException*/private static void tozip(File src,ZipOutputStream zos,String name) throws IOException {File[] files = src.listFiles();if (files.length > 0) {for (File file : files) {if (file.isFile()) {zos.putNextEntry(new ZipEntry(name + "\\" + file.getName()));FileInputStream fis = new FileInputStream(file);int b;while((b = fis.read()) != -1) {zos.write(b);}fis.close();zos.closeEntry();} else {tozip(file,zos,name + "\\" + file.getName());}}}}

8. 常用工具包

        <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version>
</dependency>

hutool文档

Java I/O流入门笔记相关推荐

  1. hadoop 2 java hdfs_Hadoop2.6.0学习笔记(二)HDFS访问

    鲁春利的工作笔记,谁说程序员不能有文艺范? 通过hadoop shell与java api访问hdfs 工作笔记之Hadoop2.6集群搭建已经将集群环境搭建好了,下面来进行一些HDFS的操作 1.H ...

  2. 《Java编程思想》读书笔记 第十三章 字符串

    <Java编程思想>读书笔记 第十三章 字符串 不可变String String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创建一个全新的String对象,以及包含修 ...

  3. Java高级开发工程师面试笔记

    最近在复习面试相关的知识点,然后做笔记,后期(大概在2018.02.01)会分享给大家,尽自己最大的努力做到最好,还希望到时候大家能给予建议和补充 ----------------2018.03.05 ...

  4. 零基础学习Java开发,这些学习笔记送给你

    因为Java具备很多特点,并且在企业中被广泛应用为此很多小伙伴选择学习Java基础开发,但是零基础学习Java技术开发需要我们制定Java学习路线图对于我们之后的学习会非常有帮助. 零基础学习Java ...

  5. Java TCP/IP Socket 编程 笔记

    http://jimmee.iteye.com/blog/617110 http://jimmee.iteye.com/category/93740 Java TCP/IP Socket 编程 笔记( ...

  6. Java 8 函数式编程学习笔记

    Java 8 函数式编程学习笔记 @(JAVASE)[java8, 函数式编程, lambda] Java 8 函数式编程学习笔记 参考内容 Java 8中重要的函数接口 扩展函数接口 常用的流操作 ...

  7. Think in Java第四版 读书笔记10 第16章 数组

    Think in Java第四版 读书笔记10 第16章 数组 数组和容器很像 但他们有一些差别 16.1 数组为什么特殊 数组与容器的区别主要在效率和存储类型 效率:数组是简单的线性序列 使得数组的 ...

  8. Think in Java第四版 读书笔记9第15章 泛型

    Think in Java第四版 读书笔记9第15章 泛型 泛型:适用于很多很多的类型 与其他语言相比 Java的泛型可能有许多局限 但是它还是有很多优点的. 本章介绍java泛型的局限和优势以及ja ...

  9. 只学一门java可行吗,java可以作为第一门编程语言学习吗

    java可以作为第一门编程语言学习吗,语言,课程,入门,计算机科学,都在 java可以作为第一门编程语言学习吗 易采站长站,站长之家为您整理了java可以作为第一门编程语言学习吗的相关内容. 十年前, ...

最新文章

  1. 记一次数据中心云平台系统项目实施
  2. CSS捡屎记 // Web开发之精通CSS
  3. 【响应式Web前端设计】css中:overflow:hidden解决塌陷
  4. JQuery 和JavaScript的区别
  5. Linux Shell脚本专栏_批量检测网站是否异常脚本_08
  6. python-变量操作-字符串
  7. easyx鼠标放置前按钮颜色_七种正确使用鼠标的好习惯,让你摆脱鼠标手的痛苦...
  8. python不定参数的函数实现_python传入不定参数是什么
  9. python大牛是什么水平_yield--Python大牛必须掌握的高端语法
  10. 一键免费下载外文文献的方式
  11. cannot import name ‘utc‘
  12. 【JVM系列JKD8】参数参考表
  13. 一次聚类引发的一系列问题(多线程篇-多线程慢于单线程)
  14. win10中sql plus中文乱码
  15. VVC帧间预测(十)帧间帧内联合预测CIIP
  16. 微星主板在有RAID的情况下在NVME的SSD上安装Win10
  17. java蓝桥杯练习 拉马车
  18. 基于微信运动场地预约小程序 毕业设计毕业论文 开题报告和效果图(基于微信小程序毕业设计题目选题课题)
  19. PCB检查-allegro PDN进行简单电源直流压降分析
  20. 软件版本(release、stable、lastest)的区别

热门文章

  1. 二嗨租车java,1嗨租车重磅福利来袭,免异地还车全新升级
  2. 史帝奇文旅项目篇——穿越式裸眼3D轨道影院
  3. 发放普通红包 php,发放普通红包
  4. telnet 不成功的症状及原因
  5. 主定理求解算法时间复杂度
  6. S32DS的图标大全
  7. 停止字jQuery中图片隐藏效果的的所有方法
  8. 哈希表 - 解决哈希冲突(总结)
  9. 查看Linux系统所有内核
  10. 【转帖】利用wsdl4j解析WSDL文件