Java基础_初识IO

IO

IO即时输入输出流,流既是流水,从一端流向另一端。而java中的输入输出流,即以java程序为中心,往外部(数据库,磁盘,网络……)既是输出流,外部(数据库,磁盘,网络……)往内部传输既是输入流。

IO流的分类在这里插入图片描述数据分类
按照处理的数据可分为,字节流和字符流。所有的数据都可以是字节流(音频,视频,doc,文本……),字符流仅仅能处理字符集合(文本)他们处理方式几乎完全相同。他们所操作的数据单元不同,字节流操作单个字节(8)位,字符流操作字符(16)位(内存中字符都为2个字节存储。getBytes()方法是将内码按编码转换为指定的外码)。

功能分类

节点流:直接从外部读写数据的流。
处理流:对于已存在的流进行封装(包装)对其性能和功能加强,装饰节点流的流

所有io操作都是基于节点流的基础上。

步骤
  1. 建立联系
  2. 选择流
  3. 操作:写出 读取
  4. 释放资源(程序中打开的文件 IO 资源不属于内存中的资源,垃圾回收无法回收,需要显示关闭。)
输入流

抽象类:InputStream 和 Reader

InputStream和Reader是所有输入流的基类,它们是两个抽象类,是所有输入流的模版,其中定义的方法在所有输入流中都可以使用。

InputStream 中包含以下3个方法(读完返回-1)

  • read(); 从输入流中读取数据的下一个字节 (一个字节一个字节读)

     读取时候,java中一个字节是int (0-255)存储的。所以转成byte字节有时候是负数。但其
     实存储的。**返回的是字节的int值**。需要转成byte字节。值是一样的。
    
  • read(byte []);

     从输入流中读取容器大小的字节,并将他们存放在byte数组中。传入的参数为存放的数组容器。
    
  • read(byte[] b,int 起始位置,int 长度)

     输入流中最多len个数据读入byte数组中。存放的byte数组的起始位置(包含),和读取的
     长度,可以又选择的去读
    

Reader 中包含以下3个方法(读完返回-1)

  • read();

     读取单个字符。返回字符对应的int值。转成char进行查看。读完了则返回-1;
    
  • read(char [] ch)

     读取容器长度的字符到char数组中。存放到char数组中。多次读会覆盖之前内容。
    
  • read(char[] ch,int 起始位置,int 长度)

     (包含起始位置)将指定长度的字符读取到char数组中
    

注意
返回结果为-1 时表明到了输入 流的结束点。
InputStream 和 Reade 都是抽象的,不能直接创建它们的实例,可以使用它们的子类。

文件节点类: FileInputStream 和 FileReader

FileInputStream 和 FileReader,它们都是节点流,直接和指定文件关联。 操作方式基本一致。

FileInputStream
FileInputStream可以用来读取任何数据(图片,视频,音乐,文字)都可以
读取文件的代码顺序
一次读b数组长度的字节数。

File file = new File("test\\bb.txt");// 建立和文件的联系
InputStream is=null; //创建流。先赋值为null。因为finally中要把流关闭,会有作用域问题
try {
 	is = new FileInputStream(file);  //建立和文件之间的流通管道
	int len =0;   //定义变量
	b= new byte[1024];
	while(-1!=(len=is.read(b))){  //将读取的字节放入byte数组中。如果返回-1说明到了末尾
		System.out.println(new String(b,0,b.length))//将字节转为String来输出。	 
	}catch (IOException e) {//异常
	e.printStackTrace();
		}finally{
			try {
				is.close();  //关闭流
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	

FileReader
FileReader只能用来读取字符内容。可以一个字符一个字符读,也可以读取char数组容量的字符
一个个读取字符

File file = new File("test\\bb.txt");  //建立文件联系
Reader read=null;   //提升作用域。
		int t=0; //字符的长度
		try {
			 read =new FileReader(file);//文件和程序之间建立管道
			 while(-1!=(t=read.read())){  //一个个进行读取,返回的是int类型的数字。
				 System.out.println((char)t); //打印字符。
			 }
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
输出流

抽象类:OutputStream 和 Writer
写入时文件不存在则会创建,但是文件路径必须完全存在。
方法与输入流的特别相似。

OutputStream中常用方法:

  • flush(); ——刷新输出流,并将内容强制写出。

  • write(byte [] b);——将byte里的数据写出到外部设备。此byte也是数据的容器,只是存储写出内容。

  • write(byte[] b,int 起始位置,int 长度)——将byte数组中,起始位置开始,指定长度的数据写出。

  • write(int b) ——写入一个字节,此字节为int型。

     3个字符组成一个中文(utf中)如果想转出的字节byte 变 int 则需要  把 (n个)256+byte值此时才是真正的int值。大于0个byte值则不变。如“中字”utf解码后
     byte值为“-28, -72, -83” 对应的int值就为“228,184,173”;
    

Writer类中常用方法

  • append(char c) ——将指定字符添加到此writer的写出流中

     可以是一个字符,也可以追加一个字符串。或者指定范围的字符串
    
  • public Writer append(CharSequence csq, int start, int end)

     指定的字符序列,参2:开始位置,参3:结束位置,左闭右开区间。
    
  • close() ——关闭流(默认有个刷新操作)

  • flush()——刷新流。将数据刷新出去。

  • write(char [] ch)——写出字符数组。

  • write(int c)——写出单个字符

  • write(String str)——写出指定字符串

  • write(String str,int 起始位置,int 长度)——同上。

文件节点流:FileOutputStream和FileWriter
FileOutputStream 和 FileWriter,它们都是节点流,直接和指定文件关联。
FileOutputStream 以字节形式输出。8位一次输出。

File file = new File("bb.txt");  //找到指定文件,没有则创建。但是如果父路径不完整,则报错
OutputStream os = null;
byte [] bytes = "aaaaaa".getBytes();
		try {
			os = new FileOutputStream(file,true);//建立流联系
			os.write(228);		//写入单个字节(int形式)
			os.write(184);		//写入单个字节(int形式)
			os.write(173);		//写入单个字节(int形式)
			os.write(bytes);    //一次写出所有数据;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				os.close();  //关闭流
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

FileWriter
以字符形式输出到指定位置。16位一次输出。

File file = new File("bb.txt");  //找到指定文件,没有则创建。但是如果父路径不完整,则报错
Writer write =null;  //创建对象
		try {
			write= new FileWriter(file);
			write.write("你好啊");//写出到流中
			write.append("ninini",0,1);//追加字符到流对象中
			write.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				write.close(); //关闭流
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

注意
关闭流 先打开的后关闭

缓冲处理类

第一类:缓冲类。用于提高效率

BufferedInputStream和 BufferedReader 对于已存在的流进行封装(包装),加强其性能,效率。
字节流直接套上即可。
字符流要是要到新增的方法所以不能使用多态

BufferedInputStream

	在读取操作的时候,其他模块并没有改变只是在字节流外套了层BufferedStream();需要传入一个
	字节流作为参数。
	InputStream is =new BufferedInputStream(new FileInputStream(src));
	读取操作同上。

BufferedReader

	因为BufferedReader中新增了一个readLine()方法,可以让我们读取一行。
	因此使用时候不能用到多态
	BufferedReader read= new BufferedReader(new FileReader(file));
	read.readLine()  //返回一行的字符串。
	其他同上,参考FileReader;

BufferedOutputStream

	同BufferedInputSream.只是嵌套在字节流外。写出方式都相同

BufferedWriter

	同BufferedReader,有个新增方法,newLine();默认打一个换行符。\n;

第二类:处理类用于处理字节流转字符流乱码问题

InputStreamReader

	普通处理的时候,如果读取的字符是gbk,而程序用的是utf时候,就必须指定字符集。并且需要最后在
	new String的地方指定字符长度和字符集。特别麻烦。

在这里插入图片描述
这时候使用处理流。InputStreamReader就非常方便——存储的是哪种字符集就必须用那种字符集解析,不然出错。

char[] cs = new char[1024];
Reader isr = new InputStreamReader(new FileInputStream(file),"gbk"); //指定读取的字符集。
int len = isr.read(cs);  //读取内容到char数组中
System.out.println(new String(cs,0,len));

OutputWriter也类似。可以指定字符集写出去。

数据处理流

可以处理基本类型+String,保留数据的类型。前提是读取顺序与写出顺序一致,否则读取数据不正确。(必须保证顺序完全一致,因为写出的是基本类型,所以我们直接打开看不懂,因为直接打开是以字符串形式显示。而我们除了程序之外写入的方式,都是以字符串形式写入的)。

数据流一样要以字节流为媒介,在字节流上包装成基本数据类型或String类型。这里没有字符流,因为字符流只能处理字符串。

DataOutputStream

DataOutputStream dos = null;
try{
	dos = new DataOutputStream(  //外层是数据流
		new BufferedOutputStream( //套一层处理流,更加效率
			new FileOutputStream) //底层还是File字节流,最基本。并且都要用到。
		);
		dos.writeInt(-1);   //写int类型的数据出去。其他类型 类似。
		dos.flush();
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				dos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

DataInputStream
readUTF() 方法用来读取字符串

DataInputStream dis = null;
try{
	dos = new DataInputStream (  //外层是数据流
		new BufferedInputStream( //套一层处理流,更加效率
			new FileInputStream) //底层还是File字节流,最基本。并且都要用到。
		);
		int i = dis.readInt();  //写int类型的数据出去。其他类型 类似。
		System.out.println(i+1); //用来证明读到的是基本类型。
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				dis.close();  //关闭流
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

必须按照类型。writeInt 就必须用readInt 来读。

对象流

作为java中最最常见的类型,有时候我们也想存储到外部设备。这个时候就必须用到了对象流
序列化:是一个用于将对象状态转换为字节流的过程,可以将其保存到磁盘文件中或通过网络发送到任何其他程序
反序列化:从字节流创建对象的相反的过程称为反序列化

对象处理流(反序列化):ObjectInputStream
ObjectInputStream能够让你从输入流中读取Java对象,而不需要每次读取一个字节。你可以把InputStream包装到ObjectInputStream中,然后就可以从中读取对象了。
条件

  • 放置到io中的对象必须实现Serializable 接口。此接口为序列化接口(标记接口)没有任何实现方法
File src=new File(srcPath); 
ObjectInputStream dis=new ObjectInputStream(               
 new BufferedInputStream(                      
   new FileInputStream(src) 
   ) 
     Object obj=dis.readObject();//读取的顺序与写出的顺序一致       必须存在才能读取 
     //获取到object对象,如果知道其类型,可以强转。然后使用方法。

序列化ObjectOutputStream
要先序列化后反序列化

File file=new File(destPath); //选择流   
OjbectOutputStream dos=new ObjectOutputStream(   
 new BueredOutputStream(  new FileOutputStream(file)   
  ) ); 
  Employee obj=new Employee (“xiaoming”,11); 
  dos.writeObject(obj); 
  dos.flush(); 
  dos.close();

//写入对象的顺序必须一致。不然出错。

我们也可以使用一些工具类来帮助我们进行读写操作
如commons-io
以下是一些commons-io中一些常用的方法
readFileToString(File file):读取文件内容并返回一个String
writeStringToFile(File file,String content):将内容content写入到file中 copyDirectoryToDirectory(File srcDir,File destDir):文件夹复制
copyFile(File srcFile,File destFile):文件复制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值