IO流

来源:互联网 发布:3d格斗类网络游排行榜 编辑:程序博客网 时间:2024/06/08 09:57

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 blocke.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);//232i=stream.read();System.out.println(i);//133//public int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中//读入缓冲区的总字节数,如果因为已经到达流末尾而不再有数据可用,返回-1byte[] 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 blocke.printStackTrace();}finally {//先创建的后关闭if(null!=fos){try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(null!=fis){try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.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 blocke.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 stubpublic static void closeIn(InputStream fis) {if(null!=fis){try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}/** * 关闭字节输出流 * @param fos 要关闭的流名称 */public static void closeOut(OutputStream fos) {if(null!=fos){try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
采用了新特性,下面留了普通关闭流的方法。