io流详解


一,什么是IO流

io是Input和Output的简称。Input代表输入,Output代表输出。输入输出都是以内存为参照数据从(网络,硬盘...)进入内存称为输入,从内存出去称为输出。

image

IO流的分类

  1. 按照流的方向
    • 数据进入内存输入流
    • 数据离开内存输出流
  2. 按处理的数据的方式
    • byte字节读取,字节流
      • 万能流,可以读取任何文件,视频,音频,txt,xslx,
    • 字符读取字符流
      • 适合读取txt文本文件
  3. 处理数据类型
    image
  4. 特点
    1. 所有的以Stream结尾的都是字节流,以reader/writer结尾的都是字符流
    2. 所有的流所有的流都实现了Java.io.Closeable接口,都有close()方法。
    3. 所有输出流都有flush()方法。

流的具体介绍

1.字节文件输入/输出流

  1. 输入流

    1. 构造方法
      • image
      • 构造流的时候需要传入一个路径,或文件代表的路径来实现连接。
    2. 常用方法
      •   int read() 从此输入流中读取一个数据字节。
        
          int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个字节数组中。
        
          int read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个字	节数组中。
        
          long skip(long n)  从输入流中跳过并丢弃 n 个字节的数据。 
        
      • 写的 时候是把特定byte大小的数组写入输入流中。
  2. 输出流

    1. 构造方法

      • image
      • FileOutPutStream(String name,boolean append)后面的布尔值表示是否往具体文件中追加文件false就会清空源文件然后写入。true表示在原具体文件的末尾追加。
    2. 常用方法

      •   void write(byte[] b) 将 b.length 个字节从指定字节数组写入此文件输出流中。 
           
          void write(byte[] b, int off, int len) 将指定字节数组中从偏移量 off 开始的 len 个字节写入此文件输出流
        	。 
          void write(int b) 将指定字节写入此文件输出流。
        
  3. 例子

    		public class FileInputstream05{
    	public static void main (String[]args) {
    	FileInputStream fis = null;
    	try{
    	fis = new FileInputStream("src/tempfile");
    	 byte[]bytes = new byte[4];
    	//循环读取文件内容
    	/*while(true){
    	//每次读取一个byte数组长度
    	intreadcount=fis.read(bytes);
    	//读取不到文件内容时停止循环
    	if(readcount==-1){
    	break;
    	}
    	System.out.print(newString(bytes,0,readcount));
    	}*/
    	int readcount = 0;
    	while((readcount=fis.read(bytes))!=-1){
    	//把读取到的数据转换为字符串,读多少转换多少个。
    	System.out.print(new String(bytes,0,readcount));
    	}
    	}catch(FileNotFoundExceptione){
    	e.printStackTrace();
    	}catch(IOExceptione){
    	e.printStackTrace();
    	}
    	finally{
    	//流不为空的时候关闭。
    	if(fis!=null){
    	try{
    	fis.close();
    	}catch(IOExceptione){
    	e.printStackTrace();
    	}
    	}
    	=========================================================================
    	
    	publicstaticvoidmain(String[]args){
    	FileOutputStreamfos=null;
    	try{
    	//如果没有该文件就会创建一个新的。并且会每次清除原来的然后写。
    	//加入true之后就会在原来的位置末尾添加写。
    	fos=newFileOutputStream("myfile",true);
    	byte[] bytes ={96,97,98,99};
    	fos.write(bytes);
    	String s ="我是一个好少年";
    	//字符串转为数组
    	byte[] bytes1 = s.getBytes();
    	fos.write(bytes1);
    	//写完之后一定要刷新。
    	fos.flush();
    	}catch(FileNotFoundExceptione){
    	e.printStackTrace();
    	}catch(IOExceptione){
    	e.printStackTrace();
    	}finally{
    	if(fos!=null){
    	try{
    	fos.close();
    	}catch(IOExceptione){
    	e.printStackTrace();
    	}
    
    

}
}

```

2.字符文件输入输出流

  • 主要处理文本文件---可以直接由文本文件打开的。.txt .java
  • 方法继承自字节流,只是承载容器由byte数组换为了char[]字节数组
publicstaticvoidmain(String[]args){
FileReaderreader=null;
try{
//构建一个字符读取对象
reader= new FileReader("src/tempfile");
char[]chars=new char[4];
intreaderCount=0;
while((readerCount=reader.read(chars))!=-1){
System.out.println(newString(chars,0,readerCount));
}
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(reader!=null){
try{
reader.close();
}catch(IOExceptione){
e.printStackTrace();
=========================================================================================

publicstaticvoidmain(String[]args){
FileWriterwriters=null;
try{
//可以在后面追加也可以清空后填写;
writers=newFileWriter("src/tempfile",true);
char[]chars={'我','是','中','国','人'};
Stringstrings="我爱我的祖国";
//可以写入字符数组,也能写入字符串。
writers.write(chars);
writers.write(strings);
//使用后一定要刷新
writers.flush();
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(writers!=null){
try{
writers.close();
}catch(IOExceptione){
e.printStackTrace();
}
![image](https://img2020.cnblogs.com/blog/2383719/202105/2383719-20210529154037862-1775859389.png)

3.缓冲流

  1. 缓冲流包括字节和字符流

    1. BufferFileReader

    2. BufferFileWriter

    3. BufferFileInputStream

    4. BufferFileOutputStream

  2. 构造方法,需要传入一个基本流
    image
    image
    image
    image

    • 构造的时候可以指定一个缓冲区的大小,不指定默认8KB
  3. 原理

    • 缓冲流就是先把读取到的数据放入自己的缓冲区域当中,减少硬盘与内存之间的访问次数。
    • 猜想普通流传输的时候是把数据放入管道,但是占用了连接,缓冲区可以减少连接的占用
    • 读取的时候可以默认读取一个字节或者指定字节读取。
    • BufferReader有一个特有方法readLine()可以一次读取一行文本数据。
  4. 例子

/*
BufferedReader:字符缓冲流,自带缓冲,
不需要再建立byte[],char[]数组。
也可以建立数组,把数据存入缓冲区。
*/
publi cclas sBufferdReaderTest01{
publicstaticvoidmain(String[]args){
	FileReader reader=null;
	BufferedReader br=null;
try{
//构造方法,需要传入一个基本流。
//被传入的流叫做节点流,传入的流叫做包装流。也叫处理流。
//BufferedReader就是包装流,FileReadr就是节点流。
reader = new FileReader("src/tempfile");
br = new BufferedReader(reader);
String readLine = null;
//带有的readLine方法可以一次读取一行,但是不会自动换行。需要使用println()。
while((readLine=br.readLine())!=null){
System.out.println(readLine);
}
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(br!=null){
//带有包装的流关闭时,只需要关闭高级流即可,里面的流会自动关闭。
try{
br.close();
}catch(IOExceptione){
e.printStackTrace();
}
}

4. 转换流(字节转换为字符流)

  1. 成员
    1. InputStreamReader--字节输入流转化为字符输入流

    2. OutPutStreamWriter--字节输出流转化为字符输出流

  2. 构造方法
    image
    image
    • 从构造方法来了,转换流的最大特点是可以指定字符的编码,可以一定程度解决编码需求
  3. 例子
publicstaticvoidmain(String[]args)throwsIOException{
//InputStreamReader把字节流转换为字符流
FileInputStreamin=newFileInputStream("src/tempfile");
//把字节流转换为字符流,返回值是一个字符流
//字节流和包装流是相对的概念,传入的那个总是相对包装的那个叫字节流。
InputStreamReaderreader=newInputStreamReader(in);
//通过字符流创建缓冲流
BufferedReaderbr=newBufferedReader(reader);
//合并格式。BufferedReaderbr=newBufferedReader(newInputStreamReader(newFileInputStream("src/tempfile")));
Stringline=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();

4.数组输入输出流

  1. 包含的类
    • ByteArrayInputStream 字节数组输出流
    • ByteArrayOutputStream 字节数组输入流
    • CharArrayReader 字符数组输入流
    • CharArrayWriter 字符数组输出流
  2. 构造方法
    image
    image
    image
    image
    • 相当于是一个数组,byte[] 或 chsr[]
    • 可以一次行把文件写入(全部或部分)
    • 写的时候是从缓冲区里面拿,减少资源占用
    • 使用后不需要关闭--本质是数组的读写
  3. 使用场景
    可以从网络上或服务器得到某些资源存入,然后返回给前端该数组。
    这些流主要是对数据进行中专作用,仅仅是会自动扩容的 容器,如果想要写入文件还需要inputStream这样的流.
//可以读取网页的html文件  点击F12显示文件
        URL url = new URL("https://www.html.cn/qa/other/19304.html");
        InputStream in = url.openStream();
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = in.read(buffer)) != -1)
        {
            output.write(buffer, 0, len);
        }
        System.err.println(new String(output.toByteArray()));
/**
*可以看到我们输入输出流并不需要对应起来
*
*/
    public static void main(String[] args) throws IOException {

        URL url = new URL("https://www.baidu.com");
        InputStream in = url.openStream();
        BufferedInputStream bfin = new BufferedInputStream(in);
        File file = new File("D:/xsq/test");
        System.out.println(file.getAbsolutePath());
        if( !file.exists()){
            file.mkdirs();
            file = new File(file.getAbsolutePath()+"/321blog.txt");
            file.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(file);
        int readCount =0;
        while((readCount=bfin.read()) != -1){
            fos.write(readCount);
        }

    }


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM