首页 > 编程语言 > 详细

Java_IO流

时间:2021-08-11 19:24:59      阅读:20      评论:0      收藏:0      [点我收藏+]

IO流分类 :

  按照数据的流向

    输入流:读数据

    输出流:写数据

  按照数据类型来分

    字节流 : 字节输入流 ; 字节输出流

    字符流 : 字符输入流 ; 字符输出流 --记事本,可以读懂的

一般来说,IO流的分类是按照数据类型来分的

字节流抽象基类

  lnputStream : 这个抽象类是表示字节输入流的所有类的超类

  OutputStream : 这个抽象类是表示字节输出流的所有类的超类

子类名特点 :子类名称都是以其父类名作为了类名的后缀

FileOutputStream : 文件输出流用于将数据写入File

FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件

--String name会自动封装成File

 FileOutputStream fos = new FileOutputStream("项目名\\fos.txt");
 /*
  做了三件事情: - 创建字节输出流对象
  1:调用系统功能创建了文件
  2:创建了字节输出流对象
  3:让字节输出流对象指向创建好的文件
 */
 fos.write(97);  //void write(int b)将指定字节写入此文件输入流 - 97对应字符"a"
 //最后释放资源 关闭此文件输出流并释放与此流相关联的任何系统资源。
 fos.close();

字节流

字节流 写数据

方法名说明
void write(int b) 将指定的字节写入此文件输出流一次写一个字节数据 ↑↑↑
void write(byte[] b) 将b.length字节从指定的字节数组写入此文件输出流一次写一个字节数组数据
ltoid write(byte[] b, int off, int len) 将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流—次写一个字节数组的部分数据
 //void write (byte[] b)
 byte[] bys1 = {97,98,99,100,101}; //对应abcde
 //byte[] getBytes ():返回字符串对应的字节数组
 byte[] bys2 = "abcde".getBytes(); //等效于上面
 ?
 fos.write(bys); //bys1,bys2结果均为添加数据"abcde"
 ?
 fos.write(bys,1,3); //写入"bcd"
 fos.close();

字节流写数据如何实现换行呢?

  window : \r\n

  linux : \n

  mac : \r

字节流写数据如何实现追加写入呢?

   public FileOutputStream(String name,boolean append)

  创建文件输出流以指定的名称写入文件

  如果第二个参数为true , 则字节将写入文件的末尾而不是开头

写数据异常处理 --标准写法↓
 FileOutputStream fos = null;
 try { //try-catch方法
  fos = new FileOutputstream("项目名\\fos.txt");
     fos.write("he11o".getBytes();
 } catch(IOException e) {
  e.printStackTrace();
 } finally {
  if(fos != nu11) {
  try {
  fos.closeo();
  } catch(IoException e) {
             e.printstackTrace();
        }
  }
 }

字节流 读数据

 //创建字节输入流对象 FileInputputStream(String name)
 FileInputputStream fos = new FileInputputStream("项目名\\fos.txt");
 //读取数据 int read()   --文件到达末尾,返回值-1
 int by = fis.read();
 System.out.println((char)by);// a,如不转换数据类型读取97
 ?
 /***读数据标准代码***/
 int by;
 while((by=fis.read())!=-1) {
  System.out.print((char)by);
   //fos.wsrite(by);写入字节
 }
 fis.close();
读数据 一次读一个字节数组
 FileInputStream fis = new FileInputStream("项目名\fos.txt");
 /*
  文件内容:
  hello
  world  
 */
 byte[] bys = new byte[5];
 //第一次
 int len = fis.read(bys); //返回读取的数据长度
 System.out.print1n(len); //5
 System.out.print1n(new string(bys,0,len)); // "hello"
 //第二次
 int len = fis.read(bys);
 System.out.print1n(len); //5
 System.out.print1n(new string(bys,0,len)); // "wor"\r\n
 //第三次
 int len = fis.read(bys);
 System.out.print1n(len); //4
 System.out.print1n(new string(bys,0,len)); // \r\n"ld""r"--最后一个r没有被覆盖
 //已经读取完,如果再读取数据,返回-1
 fis.close();
 /***读取字节标准代码***/
 byte[] bys = new byte[1024]; //1024及其整数倍
 int len;
 while((len=fis.read(bys)) != -1) {
  System.out.print(new String(bys,0,len));
   //fos.write(bys,0,len);写入数组
 }
 fis.close();

字节流 复制

根据数据源创建字节输入流对象

根据目的地创建字节输出流对象

读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)

释放资源

 FileInputStream fis = new FileInputStream("输入流对象地址\\test.txt");
 FileOutputStream fos = new FileOutputStream("输出流对象地址\\test.txt");
 int by;
 while((by=fis.read())!=-1){
  fos.write(by);
 }  //一次一个字节
 fos.close();
 fis.close();

字节流 复制图片 -案例

根据数据源创建字节输入流对象

根据目的地创建字节输出流对象

读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)

释放资源

 FileInputStream fis = new FileInputStream("输入流对象地址\\test.jpg");
 FileOutputStream fos = new FileOutputStream("输出流对象地址\\test.jpg");
 ?
 byte[] bys = new byte[1024];
 int len;
 while((len=fis.read(bys)) != -1) {
  fos.write(bys,0,len);
 }  //一次一个字节数组
 fos.close();
 fis.close();

字节流 复制视频 -案例

根据数据源创建字节输入流对象

根据目的地创建字节输出流对象读写数据

复制视频

释放资源

四种方式实现复制视频,并记录每种方式复制视频的时间

  1基本字节流一次读写一个字节       非常慢

  2基本字节流一次读写一个字节数组     比4慢,比3快

  3字节缓冲流一次读写一个字节       必1快很多,比24慢

  4字节缓冲流一次读写一个字节数组     最快(一般使用的方法)

 FileInputStream fis = new FileInputStream("地址\\test.MP4");
 FileOutputStream fos = new FileOutputStream("地址\\test.MP4");
 ?
 //2.基本字节流一次读写一个字节数组
 byte[] bys = new byte[1024];
 int len;
 while((len=fis.read(bys))!=-1) {
  fos.write(bys,0,len);
 }
 fos.close();fis.close();
 //4.字节缓冲流一次读写一个字节数组
 byte[] bys = new byte[1024];
 int len;
 while((len=fis.read(bys))!=-1) {
  fos.write(bys,0,len);
 }
 fos.close();fis.close();

字节缓冲流

BufferedOutputStream : 该类实现缓冲输出流。

  通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用

BufferedInputStream : 创建BufferedInputStream将创建一个内部缓冲区数组。

  当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节

  字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作

构造方法内容
BufferedOutputStream(OutputStream out) 字节缓冲输出流
BufferedInputStream(InputStream in) 字节缓冲输入流
 FileOutputStream fos = new FileOutputStream("地址\\test.txt");
 BufferedOutputStream b = new BufferedOutputStream(fos);
 //合并书写
 BufferedOutputStream b=new BufferedOutputStream(new FileOutputStream("."));
 //写数据
 b.write("he11o\r\n".getBytes());
 b.write("world\r\n".getBytes());
 b.close();
 ?
 ?
 BufferedInputStream bi=new BufferedInputStream(new FileOutputStream("."));
 //读数据 --一次一个字节
 int by;
 while((by=bi.read())!=-1) {
  System.out.print((char)by);
 }
 //读数据 --一次一个数组
 byte[ ] bys = new byte[1024];
 int len;
 while((len=bi.read(bys)) != -1) {
  System.out.print(new String(bys,0,len)) ;
 }
 bi.close();

字符流

字符流 = 字节流+编码表

一个汉字存储 :

  如果是GBK编码,占用2个字节

  如果是UTF-8编码,占用3个字节

如果以一个字节一个字节读取数据,将乱码,因为无法读取一个完整汉字的所有字节

 /*编码*/
 String s = "中国"; //汉字存储时,所有编码首字节一定为负数
 byte[] bys = s.getBytes(); //默认使用UTF-8
 byte[] bys = s.getBytes("UTF-8"); //[-28, -72, -83, -27, -101, -67] --默认
 byte[] bys = s.getBytes("GBK"); //[-42, -48, -71 ,-6]
 System.out.println(Arrays.toString(bys));

字符集

常见字符集有ASCII字符 集 , GBXXX字符集 , Unicode字符集...

  ASCII : 使用7位表示一个字符,共128个字符 . ASCII扩展字符集使用8位,共256个字符

  GB2312 : 简体中文码表。小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字...

  GBK : 最常用的中文码表。**是在GB2312标准基础上的扩展规范,使用了双字节编方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字...

  GB18030 : 最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个,2个或4个字节组成 . 支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字...

  Unicode : 为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF32。最为常用的UTF-8编码。

编码规则 :

  128个US-ASCIl字符,只需一个字节

  编码拉丁文等字符,需要一个字节编码

  大部分常用字(含中文),使用三个字节编码

  其他极少使用的Unicode辅助字符,使用四字节编码

编码解码

编码:

  byte[ ] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中

  byte[ ] getBytes(String charsetName);使用指定的字符集将该―String编码为一系列字节,将结果存储到新的字节数组中

解码:

  String(byte[ ] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的 String

  String(byte[ ] bytes,String charsetName):通过指定的字符集解码指定的字节数组来构造新的 string

 /*解码  使用什么方法编码就要用什么方式解码*/  
 String ss = new string(bys);  //默认使用UTF-8 "中国"
 String ss = new string(bys,"UTF-8"); //"中国"
 String ss = new string(bys,"GBK"); // --如果使用UTF-8编码会乱码
 System.out.println(ss);

字符流中编码解码问题

InputStreamReader:是从字节流到字符流的桥梁

  它读取字节,并使用指定的编码将其解码为字符

  它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集

OutputStreamWriter:是从字符流到字节流的桥梁

  是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节

  它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集

 OutputStreamWriter o = new OutputStreamWriter(new FileOutputStream("路径\\o.txt")/*,可加编码格式-默认UTF-8*/);
 o.write("中国");
 o.close();
 ?
 InputStreamReader i = new InputStreamReader(new FileOutputStream("路径\\o.txt")/*,可加编码格式-默认UTF-8*/);
 int ch;  //一次读取一个字符
 while((ch=i.read())!=-1){
  System.out.print((char)ch);
 }
 i.close();

字符流写数据

五种写数据方法(前三种一样)描述
void write(int c) 写一个字符
void write(char[] cbuf) 写入一个字符数组
void write(char[] cbuf, int off, int len) 写入字符数组的一部分
void write(String str) 写一个字符串
void write(String str,int off, int len) 写一个字符串的一部分
 //字符流不能直接写数据   void flush()  刷新流   缓冲问题
 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("路径\\osw.txt"));
 osw.write(97); //写入一个字符
 void flush(); //写入a
 ?
 char[]chs[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘};
 osw.write(chs); //abcde 写入一个字符数组
 osw.write(chs,1,3); //bcd 写入字符数组的一部分
           
 osw.write("abcde"); //abcde 写一个字符串
 osw.write("abcde",1,3); //bcd 写一个字符串的一部分
       
 osw.close(); //close流,先刷新,后关闭,关闭后不能继续写入数据

字符流 读数据

与字节流方法类似描述
int read() 一次读一个字符数据
int read(char[] cbuf) 一次读一个字符数组数据

字符流 复制Java文件 -案例

需求 : 把模块目录下的“test.java”复制到模块目录下的“Copy.java"

根据数据源创建字符输入流对象

根据目的地创建字符输出流对象

读写数据,复制文件

释放资源

 InputStreamReader isr = new InputStreamReader(new FileInputStream("目录\\test.java"));
 OutputStreamwniter osw = new OutputStreamdlriter(new FileOutputStream("目录\\Copy.java"));
 ?
 char[] chs = new char[1024];
 int len;
 while((len=isr.read(chs)) != -1) {
  osw.write(chs,0,len) ;
 }
 isr.close();osw.close();

改进 :

分析:

转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化书写,转换流提供了对应的子类

以下简化类不能规定编码格式,使用默认格式UTF-8

FileReader : 用于读取字符文件的便捷类

  FileReader(String fileName)

FileWriter : 用于写入字符文件的便捷类

  FileWriter(String fileName)

数据源和目的地的分析:

  数据源 : 项目名\ \test.java --- 读数据 --- Reader --- lnputstreamReader --- FileReader

  目的地 : 项目名\ \Copy.java --- 写数据 --- Writer --- OutputStreamWriter --- FileWriter

 FileReader fr = new FileReader("....");
 FileWriter fw = new FileWriter("....");
 ?
 char[] chs = new char[1024];
 int len;
 while((len=fr.read(chs)!=-1) {
  fw.write(chs,0,len);
 }
 fw.close();fr.close();

字符缓冲流

BufferedWriter : 将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于突多数用途

BufferedReader : 从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途

构造方法:

BufferedWriter(Writer out)

BufferedReader(Reader in)

 //BufferedWriter,BufferedReader  默认大小8192
 BufferedWriter bw = new BufferedWriter(new FileWriter("...."));
 bw.write("hello\r\n"); //写
 bw.close();
 ?
 BufferedReader br = new BufferedReader(new FileWriter("...."));
 char[] chs = new char[1024]; //读
 int len;
 while((len=br.read(chs))!=-1) {
  System.out.print(String(chs,0,len));
 }
 br.close();

字符流 复制Java文件 -缓冲改进

 BufferedWriter bw = new BufferedWriter(new FileWriter("...."));
 BufferedReader br = new BufferedReader(new FileWriter("...."));
 ?
 char[] chs = new char[1024];
 int len;
 while((1en=br.read(chs))1=-1){
 bw.write(chs,0,len);
 }
 br.close();bw.close();
 //使用字符缓冲流 特有功能
 BufferedWriter bw = new BufferedWriter(new FileWriter("...."));
 BufferedReader br = new BufferedReader(new FileWriter("...."));
 ?
 string line;
 while((1ine=br.readLine())!=null) {
  bw.write(line);  //因为上面没有读取到换行符,写入的时候需手动写入
     bw.newLine();
     bw.flush();
 }
 bw.close();br.close();

字符缓冲流 特有功能

BufferedWriter:

  void newLine() : 写一行行分隔符,行分隔符字符串由系统属性定义

BufferedReader:

  public String readLine() : 读一行文字。结果包含行的内容的字符串,不包括任何行终止字符,如果流的结尾已经到达,则为null

 BufferedWriter bw = new BufferedWriter(new FileWriter("...."));
 BufferedReader br = new BufferedReader(new FileWriter("...."));
 ?
 for(int i = 0;i < 10;i++) {
  bw.write("hello" + i);
  //bw.write("\r\n");   换行Windows系统
  bw.newLine();  //换行 推荐
  bw.flush();  //刷新流
 }
 ?
 string line;
 while((1ine=br.readLine())!=null) {
  System.out.print1n(line);  //某一行为空则返回null,结束循环
 } //此处输出不包含所有终止符 包括换行符 所以使用println
 bw.close();br.close();

总结

字节流 (有5种方式 , 一般采用字节缓冲流一次读写一个字节数组的方式)

  字节输入流:

    FilelnputStream

    BufferedInputStream

  字节输出流:

    FileOutputStream

    BufferedOutputStream

字符流 (字符流只能复制文本数据 , 有5种方式 , 一般采用字符缓冲流的特有功能)

  字符输入流(Reader):

    lnputStreamReader --FileReader

    BufferedReader

  字符输出流(Writer):

    OutputStreamWriter --FileWriter

    BufferedWriter

Java_IO流

原文:https://www.cnblogs.com/miku-jl/p/15129691.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!