IO流总结

 

IO流简介

流的定义:用来处理不同设备之间的数据传输

input:输入:文件中→java程序中:叫输入

output: 输出:java程序中→文件中,叫输出,,把内容写到文件中

按流分向:

字节流:字节输入:InputStream基类、、、字节输出流:OutputStream

字符流:字符输入:Reader、、、字符流:Writer

InputStream字节输入流

方法:

public abstract int read() throwsIOException从输入流中读取数据的下一个字节。一次读一个字节。

public int read(byte[] b) throws IOException从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。一次读一个字节数组。返回读入缓冲区的总字节数。如果因为已到达流末尾而不再有数据可用,则返回 -1。

public int read(byte[] b, int off, int len) throws IOException将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。返回读入缓冲区的总字节数。如果因为已到达流末尾而不再有数据可用,则返回 -1。

public void close() throwsIOException关闭此输入流并释放与该流关联的所有系统资源。

代码实现:一般应用

import java.io.*;
import java.util.Scanner;
/**
 * InputStream:所有字节输入流的抽象类
 * @author hp
 *
 */
public class MyInputStream{
	InputStream in;
	
	void  readmethod() throws Exception {
		byte[]  b = new byte[23];
		 in = new FileInputStream("in.txt");
		in.read(b);  //一次性读到byte中
		in.close();
	}
	
	void  readmethod2() throws Exception {
		byte[]  b = new byte[20];
		 in = new FileInputStream("in.txt");
		in.read(b,1,10);  //一次性读多少个字节到byte中,从哪个下标开始存
		in.close();
		System.out.println(new String(b));
	}
	
	void readmethod3()  throws Exception{
		int i;
		 in = new FileInputStream("in.txt");
		 OutputStream  out = new FileOutputStream("out.txt");
		 while((i=in.read())!=-1) {  //单个字节读
				out.write(i); //单个字节写
			}
		 out.close();
		in.close();
	}
	
	void    readmethod4() throws Exception{
		in = new FileInputStream(new File("in.txt"));
		Scanner sc = new Scanner(in);
		String str=null;		
		while(sc.hasNext()) {
			str=sc.nextLine();
			System.out.println(str);
		}
		sc.close();
		in.close();
	}
	
	void  readSkipmethod() throws Exception {
		byte[]  b = new byte[23];
		 in = new FileInputStream("in.txt");
		System.out.println( in.available());//获取文件大小字节数
		 in.skip(10);//跳过多少个字节数
		in.read(b);  //一次性读到byte中		
		in.close();
		System.out.println(new String(b));
	}
	
	public static void main(String[] args) throws Exception {
		MyInputStream  in = new MyInputStream();
		in.readmethod2();
		//in.readmethod3();
	//	in.readSkipmethod();

	}	
}

FileInputStream:文件字节输入流

public class FileInputStream extendsInputStream,从文件系统中的某个文件中获得输入字节

构造方法:

public FileInputStream(File file) throws FileNotFoundException,传入的参数是要读取的文件

public FileInputStream(String name) throws FileNotFoundException。传入的参数是要读取的文件名。

方法:继承父类方法。

public int read() throws IOException从此输入流中读取一个数据字节。返回下一个数据字节;如果已到达文件末尾,则返回 -1。

BufferedInPutStream:高效字节输入流

public class BufferedInputStream extendsFilterInputStream。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。

构造方法:

public BufferedInputStream(InputStream in)

public BufferedInputStream(InputStream in, int size)

public class Lianxi4 {

    publicstatic void main(String[] args) throws IOException {

       FileInputStreamfs = new FileInputStream("a.txt");

       BufferedInputStreambis = new BufferedInputStream(fs);

       byte[] b = new byte [10];

       intlen2;

       while((len2= (bis.read(b, 2,6))) != -1){

           Strings = new String(b,2,6);

           System.out.println(s);

       }

       bis.close();

    }

}

OutputStream字节输出流

这是一个抽象类,是所有字节数出流的父类,输出流接收输出字节,并将它们发送到一些接收器,定义OutputStream类,应用至少一个接收器接收字节

 

返回值类型

方法名

方法简介

voidflush( )刷新输出流,是缓存数据被写出来
voidwrite(byte [ ] b)写b.length 字节从指定的字节数组的输出流
voidwrite(byte [ ] b, int off, int len)写len字节从字节数组数据中到输入流
abstract intwrite( int b )将指定的字节写入该输出流中
voidclose( )关闭流

FileOutputStream:(文件字节数出流)

主要功能是从源文件写入资料到指定的文件中

构造方法:

public FileOutputStream(File file) throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果文件不存在,自动创建文件,如果父目录不存在,报错。

public FileOutputStream(String name) throws FileNotFoundException创建一个向具有指定名称的文件中写入数据的输出文件流。

public FileOutputStream(String name, boolean append) throws FileNotFoundException创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。如果第二个参数是false,则每次都重新写入。

public FileOutputStream(File file, boolean append) throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。如果第二个参数是false,则每次都重新写入。

方法:继承父类方法。在传入字符串时,可以使用String的getBytes()方法将字符串转为byte数组,再使用public void write(byte[] b)方法写入数据。

public void write(int b) throws IOException将指定的字节写入此输出流。一次只能写一个字节,不能写中文,因为一个中文汉字在GBK编码中占2个字节。

 publicstatic void main(String[] args) throws IOException {

       Filef = new File("a.txt");//写文件时如果文件不存在,会自动创建,但是如果父目录不存在,会报错。

       FileOutputStreamos = new FileOutputStream(f);

       os.write(98);//一次写入一个字节

       os.write('}');

       os.write("98".getBytes());//写入的是98

       byte[] b = {'a','n','g','w','u'};

       os.write(b);//一次写入一个字节数组

       os.write(b,0, b.length);

       os.write("云和数据".getBytes());//通过String类的getBytes()方法(返回byte数组)将字符串转为byte数组。

       os.close();  

    }

}

BufferedOutputStream(高效字节输出流):

public class BufferedOutputStreamextendsFilterOutputStream,FilterOutputStream是OutputStream的子类。在创建 BufferedOutputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。

构造方法:

public BufferedOutputStream(OutputStream in),传入的参数是普通的字节输出流对象。

public BufferedOutputStream(OutputStream out,int size),size是缓冲区大小,一般不设置,有默认值。缓冲区长度不要太大,否则浪费空间。

方法:继承父类方法。

      特别注意:高效流中必须调用flush方法才能写出成功,因为在高效流中有缓冲区,每次调用write方法时其实是先把数据写在缓冲区,调用flush方法时才写到底层输出流中。

为什么不写flush,只写close也可以写入成功?

因为close方法底层其实调用了flush方法,即在关闭时也进行刷新了,我们一般把flush和close都写上。

      为什么普通流不需要刷新?

因为普通=流每一次write方法时都调用了底层资源,直接写在底层数据流中。

代码示例

package io;

import java.io.BufferedOutputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

public class Lianxi3 {

    publicstatic void main(String[] args) throws IOException {

       FileOutputStreamos = new FileOutputStream("cc.txt");//创建普通流,自动生成文件

       BufferedOutputStreambos = new BufferedOutputStream(os);//传入普通输出流对象,创建高效流

        byte [] c = {'w','y','h','j','a','v','a'};

       bos.write(c,2,3);//从数组的索引为2的元素开始长度为3的元素写出:hja

       bos.flush();//必须刷新或关闭

       bos.close();//关闭流时只需要关闭高效流即可,因为高效流的底层关闭了普通流。

    }

}

字符输出流:Writer

public abstract class Writerextends Object,抽象类,子类:BufferedWriter、OutputStreamWriter。。。。

java.io.OutputStreamWriter的子类:FileWriter。

文件字符输出流:FileWriter

功能方法与高效字节输出流相同,,但是字符输出流只能写文本(图片,音乐,视频,都不能使用字符流)

构造方法:

public FileWriter(File file) throwsIOException

public FileWriter(File file, boolean append)throws IOException

public FileWriter(String fileName, booleanappend) throws IOException

public FileWriter(String fileName) throwsIOException

用法与普通字节输出流相同。

方法:

public void write(int c) throws IOException,写入单个字符,参数是要写入字符的int。

public void write(char[] cbuf, int off, intlen) throws IOException写入字符数组的某一部分。cbuf - 字符缓冲区,off - 开始写入字符处的偏移量

,len - 要写入的字符数 。

public void write(String str, int off, int len) throwsIOException写入字符串的某一部分。str - 字符串,off - 开始写入字符处的偏移量,len - 要写入的字符数 。

public void flush() throws IOException刷新该流的缓冲。

public void close() throws IOException,关闭流。

publicclass Lianxi6 {

    public static void main(String[] args)throws IOException {

       FileWriter f1 = newFileWriter("m.txt");

       f1.write('你');

       char [] c ={'i','l','o','v','e','j','a','v','a'};

       f1.write(c,2,4);

       String s = "好好学习天天向上";

       f1.write(s, 3, 5);

       f1.flush();

       f1.close();      

    }

}

高效字符输出流:BufferedWriter

public class BufferedWriter extends Writer,将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入,可以指定缓冲区的大小,或者接收默认的大小,在大多数情况下,默认值就都用

构造方法:

publicBufferedWriter(Writer out)创建一个使用默认大小输出缓冲区的缓冲字符输出流。

publicBufferedWriter(Writer out, int sz)创建一个使用给定大小输出缓冲区的新缓冲字符输出流。 sz - 输出缓冲区的大小,是一个正整数 。

需要传入普通字符输出流。(必须刷新才能写入成功

方法:

与文件字符输出流相同。

publicvoid newLine() throws IOException写入一个行分隔符。(换行)

字符输入流:Reader

publicabstract class Readerextends Objectimplements Readable, Closeable。是抽象类,子类:BufferedReader,InputStreamReader(子类:FileReader)

FileReader:(文件字符输入流)

publicclass FileReader extends InputStreamReader。用于读取字符流。

构造方法:

publicFileReader(File file) throws FileNotFoundException

publicFileReader(String fileName) throws FileNotFoundException

方法:

publicint read() throws IOException,读取单个字符。返回作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1。

publicint read(char[] cbuf) throws IOException,将字符读入数组。返回

读取的字符数,如果已到达流的末尾,则返回 -1 。

publicabstract int read(char[] cbuf, int off, int len) throws IOException

将字符读入数组的某一部分。返回读取的字符数,如果已到达流的末尾,则返回 -1 。

代码示例:

publicclass Lianxi7 {

    public static void main(String[] args)throws IOException {

       FileReader f1 = newFileReader("m.txt");

    /*  intlen;

       while ((len = f1.read()) != -1) {//读取一个字符

           System.out.println((char)len);        

       }*/

       char [] c = new char [4];

       int len1;

       while ((len1 = f1.read(c,1,3)) != -1) {//读取数组

           System.out.println(Arrays.toString(c));         

       }     

       f1.close();

    }

}

高效字符输入流:(BufferedReader)

public class BufferedReader extends Reader,从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

构造方法:

public BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流。

public BufferedReader(Reader in, int sz)创建一个使用指定大小输入缓冲区的缓冲字符输入流。sz -输入缓冲区的大小 。

方法:

继承父类方法。

publicString readLine() throws IOException读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。 返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null 。

InPutStreamReader类:字节字符转换输入流

public class InputStreamReaderDemo {
	public static void main(String[] args) throws IOException {
		//1.实例化File的对象
		//File file = new File("file/input1.txt");
		
		//2.实例化转换输入流的对象
		//注意:当一个流的存在的意义是为了实例化另外一个流,则这个流不需要手动进行关闭
		//InputStream input = new FileInputStream(file);
		//InputStreamReader reader = new InputStreamReader(input);
		//使用默认的字符集【GBK】进行实例化转换流
		//InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("file/input1.txt")));

		//使用指定字符集进行实例化转换流
		//字符集一般使用字符串直接传参,不区分大小写,但是,如果字符集书写有误的话,则会跑出java.io.UnsupportedEncodingException
		InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("file/input1.txt")),"UTF-8");
		
		//3.读取
		char[] arr = new char[16];
		int len = 0;
		
		while((len = reader.read(arr)) != -1) {
			String string = new String(arr, 0, len);
			System.out.println(string);
		}
		
		reader.close();
	}
}

OutPutStreamWriter类:字节字符转换输出流

public class OutputStreamWriterDemo {
	public static void main(String[] args) throws IOException {
		//需求:将一段文本以utf-8的格式写入到文件中【注,文件格式为默认格式】
		//1.实例化FIle对象
		//注意:对于所有的输出流而言,文件可以不存在,在进行写入的过程中可以自动进行创建
		//但是,对于所有的输入流而言,文件必须先存在,然后才能操作,否则,会抛出FileNotFounedException
		File file = new File("file/output1.txt");
		
		//2.实例化转换输出流
		//如果不想覆盖源文件中的内容时,则在传参的时候,设置一个参数为true
		OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file,true), "utf-8");

		//3.写入
		writer.write("家客户放假啊刚回家");
		
		//4.刷新
		writer.flush();
		
		//5.关闭
		writer.close();
	}
}

SequenceInputStream

一个SequenceInputStream代表其他输入的逻辑连接,就是将两个或以上输入流进行合并

import java.io.*;
public class MySequenceInputStream {

	public static void main(String[] args) throws Exception {
		BufferedOutputStream   bout = new BufferedOutputStream(new FileOutputStream("test.txt"));

		FileInputStream in1=new FileInputStream("buff.data");
		FileInputStream in2 = new FileInputStream("data.txt");
		BufferedInputStream   bin1 = new BufferedInputStream(in1);//缓冲
		BufferedInputStream   bin2 = new BufferedInputStream(in2);
		SequenceInputStream seq = new SequenceInputStream(bin1,bin2);
		int i;
		while((i=seq.read())!=-1) {
			bout.write(i);
		}
		
		bout.close();
		seq.close();
		
	}

}

ByteArrayOutputStream

ByteArrayInputStream

输入和输出都是从文件中来的,当然,野了将输出的位置设置在内存上,

这个类实现了一个输出流,其中的数据被写入一个字节数组,当数据被写入时,缓冲区会自动边长

数据可以用toByteArray()和toString()检索

public class TextDemo02 {
	public static void main(String[] args) throws IOException {
		//定义一个字符串,全部由大写字母组成
		String string = "HELLOWORLD";
		
		//内存输入流
		//向内存中输出内容,注意:跟文件读取不一样,不设置文件路径
		ByteArrayInputStream bis  = new ByteArrayInputStream(string.getBytes());
		//内存输出流
		//准备从内存中读取内容,注意:跟文件读取不一样,不设置文件路径
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		
		int temp = 0;
		//read()方法每次只读取一个字符
		while((temp = bis.read()) != -1) {
			//将读取的数字转为字符
			char c = (char)temp;
			//将字符变为大写
			bos.write(Character.toLowerCase(c));
		}
		//循环结束之后,所有的数据都在ByteArrayOutputStream中
		//取出内容,将缓冲区内容转换为字符串
		String newString = bos.toString();
		
		//关闭流
		bis.close();
		bos.close();
		System.out.println(newString);
	}
}

对象流:对象序列化

如果将一个对象写入到本地文件中,被称为对象的序列化;

如果将一个对象从本地文件中读取出来,被称为对象反序列化

注意:一个对象流只能操作一个对象,如果试图操作多个对象的话,可以将对象放到数组中,将对象数组的对象进行序列化,写入到本地文件中,再次读出来,获取到的仍然是集合对象,然后将集合进行遍历


public class ObjectStreamDemo {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//objectOutputStreamUsage();
		objectInputStreamUsage();
	}

	// 写:将对象进行序列化
	public static void objectOutputStreamUsage() {
		//1.实例化一个Person的对象
		Person person =  new Person("张三", 10, 'B');
		
		//2.实例化一个对象输出流的对象
		ObjectOutputStream output = null;
		try {
			output = new ObjectOutputStream(new FileOutputStream(new File("file/person.txt")));
		
			//3.将对象写入到流中
			output.writeObject(person);
			
			//4.刷新
			output.flush();
		
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally {
			try {
				output.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	// 读:反序列化
	public static void objectInputStreamUsage() {
		//1.实例化对象输入流的对象
		try {
			ObjectInputStream input = new ObjectInputStream(new FileInputStream(new File("file/person.txt")));
		
			//2.读取
			Object object = input.readObject();
			
			//3.对象的向下转型
			if(object instanceof Person) {
				Person p = (Person)object;
				System.out.println(p);
			}
		
		} catch (FileNotFoundException e) {

			e.printStackTrace();
		} catch (IOException e) {
		
			e.printStackTrace();
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
		}
	}
}	

RandomAccessFile类

 

public class TextDemo01 {
	public static void main(String[] args) throws Exception {
		RandomAccessFile file = new RandomAccessFile("file.txt", "rw");
		// 以下向file文件中写数据
		file.writeInt(20);// 占4个字节
		file.writeDouble(8.236598);// 占8个字节
		//这个长度写在当前文件指针的前两个字节处,可用readShort()读取
		file.writeUTF("这是一个UTF字符串");
		file.writeBoolean(true);// 占1个字节
		file.writeShort(395);// 占2个字节
		file.writeLong(2325451l);// 占8个字节
		file.writeUTF("又是一个UTF字符串");
		file.writeFloat(35.5f);// 占4个字节
		file.writeChar('a');// 占2个字节
		//把文件指针位置设置到文件起始处
		file.seek(0);

		// 以下从file文件中读数据,要注意文件指针的位置
		System.out.println("——————从file文件指定位置读数据——————");
		System.out.println(file.readInt());
		System.out.println(file.readDouble());
		System.out.println(file.readUTF());
		
		//将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。
		file.skipBytes(3);
		System.out.println(file.readLong());
		
		//跳过文件中“又是一个UTF字符串”所占字节
		//注意readShort()方法会移动文件指针,所以不用写2。
		file.skipBytes(file.readShort()); 
		System.out.println(file.readFloat());

		// 以下演示文件复制操作
		System.out.println("——————文件复制(从file到fileCopy)——————");
		file.seek(0);
		RandomAccessFile fileCopy = new RandomAccessFile("fileCopy.txt", "rw");
		int len = (int) file.length();// 取得文件长度(字节数)
		byte[] b = new byte[len];
		//全部读取
		file.readFully(b);
		fileCopy.write(b);
		System.out.println("复制完成!");
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值