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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

NoteLoopy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值