IO流

IO流

读取流: 读取数据

输出流: 写出数据

按照数据类型

字节流:任何文件都可以被看成是一个字节数组,字节流可以操作任何文件。

字符流:只能操作文本类型的文件

字节流基类

输出流基类:OutputStream

输入流基类:InputStream

字符流基类

输出流基类:Writer

输入流基类:Reader

字节流和字符流的子类命名方式都是以他们的基类作为后缀名的

在写入过程中,会先判断硬盘上有没有对应的文件,如果没有就创建,然后建立一个通道,通过这个通道写入字节。当数据写入结束以后,通道就应该关闭掉,不然会占用资源,会导致内存泄漏;当内存泄漏过多就会导致内存溢出。

public static void main(String[] args) throws Exception {
	FileOutputStream stream = null;
	try {
		stream = new FileOutputStream("/Users/yoofale/Desktop/haha.txt");
		byte[] bytes = "腰子啊".getBytes();
		stream.write(bytes);
		System.out.println(bytes.length);
		stream.write(bytes, 0, 6);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally {
		stream.close();
		
	}
}

标准格式就是先在外面定义一个FileOutPutStream,并初始化。try中前面一旦发生错误就不会继续执行,没法继续下面的关闭通道释放资源,所以将关闭通道放在finally中,确保安全。

 

 

字节流写数据

 

FileOutputStream的构造方法

FileOutputStream(File file) 创建一个向指定File文件写入数据的文件输出流

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

写入数据

public void write(int b)

public void write(byte[] b)

public void write(byte[] b,int off,int len)

 

 

如何追加和换行写入?

追加

new FileOutputStream(file, append)True写在文件末尾处,false写在文件开头

换行

byte[] bytes = "腰子啊\r\n".getBytes();  字符串后面加\r\n

 

public static void main(String[] args) {
//		public FileInputStream(File file)和指定文件建立一个读取通道
//		public FileInputStream(String name)和指定文件建立一个读取通道
		try {
			stream = new FileInputStream("/Users/yoofale/Desktop/haha.txt");
			//public int read()从读取通道中读取一个字节,这个方法是阻塞的
			int i=stream.read();
			System.out.println(i);//232
			i=stream.read();
			System.out.println(i);//133
//			public int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
//			读入缓冲区的总字节数,如果因为已经到达流末尾而不再有数据可用,返回-1
			byte[] buf=new byte[1024];
			int read = stream.read(buf);
			String string = new String(buf,0,read);
			System.out.println(string);

		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

两种读取,一次读取一个字节,一次读取一个数组。一次读取一个数组比一次读取一个字节效率高得多。


 

运用字节流复制文件

public static void main(String[] args) {
//		先读后写,文件字节读取流
		FileInputStream fis=null;
		FileOutputStream fos=null;
		try {
			fis = new FileInputStream("/Users/yoofale/Desktop/haha.txt");
			fos = new FileOutputStream("/Users/yoofale/Desktop/hehe.txt");
//			读的时候,需要定义一个缓冲区容器,一次多取一点
			byte[] buf=new byte[1024];
//			定义一个变量,用于接受每次读取的字节数
			int len =-1;
//			循环读写
			while((len=fis.read(buf))!=-1){
				fos.write(buf,0,len);
			}
			System.out.println("拷贝成功");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//先创建的后关闭
			if(null!=fos){
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null!=fis){
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
	}

 

 

 

代码分析:标准格式。唯一需要注意的就是,先创建的流要后关闭。因为所有的内容全都获取到,不能只是一部分。如果读取到的内容不为-1,开始写入内容。,读多少就写多少。

 

简化关闭流

将两个关闭封装成方法,打包放入IOUtils中(将private换成public,不要带main),想要调用方法,IOUtils.closeIn()即可

 

 

JDK1.7新特性,可以在用完流的时候自动关闭;在try()里面自动只能用于创建流.不能创建其他。执行到try结束之后,流自动关闭

public static void main(String[] args) {
		// 先读后写,文件字节读取流

		try (FileInputStream fis = new FileInputStream("/Users/yoofale/Desktop/haha.txt");
				FileOutputStream fos = new FileOutputStream("/Users/yoofale/Desktop/hehe.txt");) {

			// 读的时候,需要定义一个缓冲区容器,一次多取一点
			byte[] buf = new byte[1024];
			// 定义一个变量,用于接受每次读取的字节数
			int len = -1;
			// 循环读写
			while ((len = fis.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}
			System.out.println("拷贝成功");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 

完整版封装复制文件代码

 

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOUtils {
	public static void copyFile(String srcPath, String destPath){
		try (FileInputStream fis = new FileInputStream(srcPath);
				FileOutputStream fos = new FileOutputStream(destPath);) {

			// 读的时候,需要定义一个缓冲区容器,一次多取一点
			byte[] buf = new byte[1024];
			// 定义一个变量,用于接受每次读取的字节数
			int len = -1;
			// 循环读写
			while ((len = fis.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}
			System.out.println("拷贝成功");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭字节读取流
	 * @param fis 要关闭的流名称
	 */
		// TODO Auto-generated method stub
		public static void closeIn(InputStream fis) {
			if(null!=fis){
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		/**
		 * 关闭字节输出流
		 * @param fos 要关闭的流名称
		 */
		public static void closeOut(OutputStream fos) {
			if(null!=fos){
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	

}

采用了新特性,下面留了普通关闭流的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值