IO流的分类和基本操作

1: IO流的概念

流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出。

2: IO流的分类

按照流的流向分类
输入流: 只能从中读取数据,而不能向其写入数据。
输出流:只能向其写入数据,而不能向其读取数据。

java的输入流主要是InputStream和Reader作为基类,而输出流则是主要由outputStream和Writer作为基类。

按照类型划分
字节流:操作的单元是数据单元是8位的字节字节流主要是由InputStream和outPutStream作为基类
字符流:字符流操作的是数据单元为16位的字符而字符流则主要有Reader和Writer和 FileReader FileWriter作为基类
具体区别请参考:字节流和字符流的区别
按照性能划分
缓冲区流:BufferedWriter和BufferedWriter
转换流
字节流到字符流之间的桥梁,使用特定字符集合读取byte并解码字符

底层是字节流,如果需要将其转换成字符内容处理的话,就可以使用转换流
装饰模式实现

InputStreamReader-------new InputStreamReader(InputStream is,charset)
OutputStreamWriter

常用流

流分类使用分类字节输入流字节输出流字符输入流字符输出流
-抽象基类InputStreamOutputStreamReaderWriter
节点流访问文件FileInputStreamFileOutStreamFileReaderFileWriter
处理流缓冲流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
处理流转换流InputStreamReaderOutputStreamWriter
处理流打印流PrintStreamPrintWriter

流的结构图
在这里插入图片描述
流的常用用法
通用用法:
1.flush() 清理流,將流中的数据写入到目标设备上
2.close() 关闭流,隐含着flush()操作。

字符流

输出
FileWriter访问文件
将hello world输入到d盘的txt中

import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  FileWriter writer=null;
try {
  writer=new FileWriter("d:\\hello.txt");
 writer.write("hello world");
 writer.flush();
} catch (IOException e) {
 e.printStackTrace();
}
finally {
 try {
  if(writer!=null) {
  writer.close();
  }
 } catch (IOException e) {
  e.printStackTrace();
   }
  }
 }
}

结果:

D盘下的hello.txt中的文字是:hello world

BufferedWriter缓冲区写入

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterDemo {
 public static void main(String[] args) {
try {
 String line=System.getProperty("line.separator");
 BufferedWriter bw=new BufferedWriter(new FileWriter("d:\\hi.txt",false));
 bw.write("hello"+line);
 bw.write("hello1"+line);
 bw.write("hello2"+line);
 bw.write("hello3"+line);
 bw.close();
} catch (Exception e) {
 e.printStackTrace();
}
 }
}

结果:

在hi.txt中
hello
hello1
hello2
hello3

BufferedWriter缓冲区大小的区别

public static void main(String[] args) throws Exception {
  int size=1024;
  for(int i=1;i<=1024*2;i=i*2) {
   long strat=System.currentTimeMillis();
   BufferedWriter writer=new BufferedWriter(new FileWriter("d:\\hello.txt"),i*size);
   for(int i1=0;i1<10000000;i1++) {
    writer.write("java  ");  
   }
   writer.close();
   long duration=System.currentTimeMillis()-strat;
   System.out.println(i+"k:"+duration);
  }
 }

结果:

1k:751
2k:666
4k:580
8k:601
16k:586
32k:594
64k:586
128k:582
256k:594
512k:634
1024k:643
2048k:660

BufferedWriterandFileWriter
检测有无缓冲区的区别
向文件中输入1-10000000,看看哪个时间少

import java.io.FileWriter;
import java.io.IOException;
import org.junit.Test;
public class BufferWriterandFileWriter {
 //FileWriter
 public static void main(String[] args) {
try {
 long l=System.currentTimeMillis();//获取系统当前毫秒数
 FileWriter writer=new FileWriter("d:\\hello.txt");//建立文件
 for(int i=0;i<10000000;i++) {//循环输入
  writer.write(i+" ");
 }
 writer.close();
 System.out.println(System.currentTimeMillis()-l);//输出时间差
} catch (IOException e) {
 e.printStackTrace();
}
//BufferedWriter
try {
long l=System.currentTimeMillis();
BufferedWriter writer=new BufferedWriter(new FileWriter("d:\\he.txt",false));
for(int i=0;i<10000000;i++) {
 writer.write(i+" ");
}
writer.close();
System.out.println(System.currentTimeMillis()-l);
} catch (IOException e) {
e.printStackTrace();
}
 }

结果:

1444
918
显然有缓冲区的使用时间少

读取

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public static void main(String[] args) {
  FileReader reader=null;
try {
  reader=new FileReader("d:\\hello.txt");
 char [] buffer=new char[3];//缓冲区
  //int length=reader.read(buffer);//返回长度
  int len=-1;
  while((len=reader.read(buffer))!=-1) {
   System.out.print(new String(buffer,0,len));
   //打印的时候只打出0-这次读取的长度就行,要不加length
   //就会出现上次的数据。
  }
} catch (Exception e) {
 e.printStackTrace();
}
finally {
 if(reader!=null) {
  try {
   reader.close();
  } catch (IOException e) { 
   e.printStackTrace();
  }
 }
}
 }
}


结果:

假设hello.txt中是hello world
则输出:hello world
如果不加length 就会出现hello worldrl

引进Test测试:单元测试框架
方便进行测试使用
ReaderAndBufferedReader
Reader:

@Test
 public  void readFile() throws Exception {
  FileReader reader =new FileReader("d:\\hello.txt");
 long start=System.currentTimeMillis();
 int c=-1;
 while((c=reader.read())!=-1) {}
 reader.close();
 System.out.println(System.currentTimeMillis()-start);
 }

结果:

1579

BufferedReader

@Test
 public void readFileWithBuffered2() throws Exception{
  BufferedReader br=new BufferedReader(new FileReader("d:\\hello.txt"));
  long start =System.currentTimeMillis();
  char [] cbuf=new char[140000000];
  br.read(cbuf);
  br.close();
  System.out.println(System.currentTimeMillis()-start); 
 }

结果:

496

显然Buffered使用时间少

readLine()
读取一整行。不含有行结束符
一行行读

String line =null;
while(((line=br.readLine())!=null)){
System.out.println(line);
}

测试LineNumberReaderTest

public void LineNumberReaderTest() throws Exception{
LineNumberReader reader=new LineNumberReader(new FileReader("d:\\hello.txt"))
String line=null;
reader.setLineNumber(100);//改变行号
while((line=reader.readLine())!=null){
 System.out.println(reader.getLineNumber());
}
}

字节流

字节流与字符流类似,以上字符流的Buffered的区别与字节流的类似,不在叙述
使用字节流复制图片

@Test
  public void copyImage() throws Exception {
 //文件输入流(字节)
  FileInputStream fin=new FileInputStream("D:\\beijing.jpg");
    //文件输出流(字节)
     FileOutputStream fout=new FileOutputStream("D:\\beijing2.jpg");
  byte[]buffer=new byte[1024];
  int len=-1;
  //文件尾
  while((len=fin.read(buffer))!=-1) {
      fout.write(buffer,0,len);
  }
  fin.close();
  fout.close();
  }

结果:

在D盘下会出现一个beijing2.jpg的图片与beijing.jpg完全相同

使用文件输出流写文本文件

@Test
 public void writerFileWithFileOutputStream() throws Exception {
  System.out.println(Charset.defaultCharset());
 String str="helloworld";
  FileOutputStream fos=new FileOutputStream("d:\\hi.txt");
 //编码。
  // gbk  7bytes
  //iso 6bytes  丢数据
  //utf-8    8 bytes
  fos.write(str.getBytes("gbk"));
  fos.close();
  System.out.println("over");
  }

结果:

使用不同的编码,字节数不一样

使用文件输入流读取文件

 @Test
 public void readFileWithFileInputStream2() throws Exception {
  FileInputStream fis=new FileInputStream("d:\\hi.txt");
  char c= (char) fis.read();
  System.out.println(c);
 }

** 跳过字节,可前可后**

@Test
 public void skipByteTest() throws Exception {
  FileInputStream fis=new FileInputStream("d:\\hi.txt");
 int c=fis.read();
  while((c=fis.read())!=-1) {
   fis.skip(1);
  System.out.println((char)c);
  
  }
 }

结果:

假设原本hi.txt为hello world
则输出:
e
l
 
o
l

使用字符流非缓冲复制文件内容:

ublic class FileCopyDemo {
public static void main(String []args) {
 FileReader reader=null;
 FileWriter writer=null;
 try {
  reader=new FileReader("d:\\yuanlai.txt");
  writer =new FileWriter("d:\\fuzhi.txt",false);
  int len=-1;
  char [] buffer=new char[4];
  while((len=reader.read(buffer))!=-1) {
   writer.write(buffer,0,len);
   writer.flush();
  }
 }
  catch(Exception e) {
   e.printStackTrace();
  }
  finally {
   try {
    if(reader!=null) {
     reader.close();
    }
    if(writer!=null)
    {
     writer.close();
    }
   }catch(Exception e) {
    e.printStackTrace();
   }
  }
 System.out.println("over");
  }

结果:两个文件夹下的内容都变成yuanlai.txt中内容的

转换流

使用转换流,桥梁(字节–>字符)
使用转换流读取文本

 @Test
 public void read() throws Exception, Exception {
  InputStreamReader reader=new InputStreamReader(new FileInputStream("d:/c.txt"),"gbk");
  char[]buffer=new char[1024];
  int len=-1;
  while((len=reader.read(buffer))!=-1) {
  System.out.println(new String(buffer,0,len)); 
  }
  reader.close();
 }

结果:

文件c.txt中为a中b
gbk编码:a中b
utf-8:a??b
unicode:懖??

打印流

改变系统的out输出流向
默认console,也就是控制台

@Test
public void sysoutTest() throws Exception {
  //改变系统的输出流向
 PrintStream ps=new PrintStream(new FileOutputStream("d:/log.log"));
  System.setOut(ps);
  System.out.println("hello world");
}

结果:

hello world 输入到了log.log

从控制台输入字符,打印在控制台

@Test
 public void systemin() throws Exception {
   System.out.println(System.in);
  BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
  while(true) {
   String line=reader.readLine();
   if("exit".equals(line)) {
    System.exit(-1);
   }
   System.out.println(line);
  }
 }

结果:

从控制台输入啥就直接输出啥
输入exit的时候就停止了

使用缓冲区转换流
从文件夹中输出到控制台

@Test
 public void systemin() throws Exception {
  //改变系统的输入方向
  System.setIn(new FileInputStream("d:/d.txt"));
  System.out.println(System.in);
  BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
  while(true) {
   String line=reader.readLine();
   if("exit".equals(line)) {
    System.exit(-1);
   }
   System.out.println(line);
  }
 }

结果:

d.txt中的内容就输出到屏幕了
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
《Java 基础核心总结》 Java 概述 什么是 Java2 Java 的特点Java 开发环境 JDK JRE Java 开发环境配置 Java 基本语法 数据类型基础语法运算符 Java 执行控制流程条件语句 if 条件语句 if...else 条件语句if...else if 多分支语句switch 多分支语句 循环语句 while 循环语句do...while 循环for 循环语句 跳转语句 break 语句 continue 语句面向对象 类也是-种对象对象的创建 属性和方法 构造方法 方法重载 方法的重写 初始化 类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 Throwable 常见的 Exception 与 Exception 有关的 Java 关键字 throws 和 throw try 、finally 、catch 什么是 Error 内部类 创建内部类集合 Iterable 接口顶层接口 ArrayList Vector LinkedList 类Stack HashSet TreeSet LinkedHashSet 类 PriorityQueue HashMap TreeMap 类 LinkedHashMap 类 Hashtable 类IdentityHashMap 类WeakHashMap 类 Collections 类集合实现类特征图 泛形 泛型的使用 用泛型表示类 用泛型表示接口泛型方法 泛型通配符 反射 Class 类Field 类Method 类ClassLoader 类 枚举 枚举特性 枚举和普通类-样枚举神秘之处 枚举类 I/O File 类 基础 IO 类和相关方法InputStream OutputStream Reader 类Writer 类 InputStream 及其子类 OutputStream 及其子类Reader 及其子类Writer 及其子类 注解 关于 null 的几种处理方式大小写敏感 null 是任何引用类型的初始值 null 只是-种特殊的值使用 Null-Safe 方法null 判断 关于思维导图 Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 传统的 BIO BIO NIO 和 AIO 的区别什么是流 流的分类 节点流和处理流 Java IO 的核心类 File Java IO 流对象 字节流对象InputStream OutputStream 字符流对象Reader Writer 字节流与字符流的转换新潮的 NIO 缓冲区(Buffer)通道(Channel) 示例:文件拷贝案例 BIO 和 NIO 拷贝文件的区别操作系统的零拷贝 选择器(Selectors) 选择键(SelectionKey) 示例:简易的客户端服务器通信 集合 集合框架总览 -、Iterator Iterable ListIterator 二、Map 和 Collection 接口Map 集合体系详解 HashMap LinkedHashMap TreeMap WeakHashMap Hashtable Collection 集合体系详解 Set 接口 AbstractSet 抽象类SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象类LinkedList ArrayDeque PriorityQueue 反射的思想及作用 反射的基本使用 获取类的 Class 对象构造类的实例化对象获取-个类的所有信息 获取类中的变量(Field) 获取类中的方法(Method) 获取类的构造器(Constructor) 获取注解 通过反射调用方法反射的应用场景 Spring 的 IOC 容器反射 + 抽象工厂模式 JDBC 加载数据库驱动类反射的优势及缺陷 增加程序的灵活性破坏类的封装性 性能损耗 代理模式 静态代理与动态代理常见的动态代理实现JDK Proxy CGLIB JDK Proxy 和 CGLIB 的对比动态代理的实际应用 Spring AOP 变量 变量汇总实例变量 实例变量的特点全局变量 静态变量 静态变量的特点类变量 局部变量

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NoteLoopy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值