Java之IO流解读

Java IO流

编程语言的IO类库经常使用流这个抽象的概念,它将所有的数据源和数据接收器表示能够产生或者接受数据的对象。在java中,Java中IO类库不仅能面向字节的类库,而且还有面向字符和基于Unicode的类。

IO流屏蔽了实际的IO设备中处理数据的细节:

1、字节流对应原生的二进制数据

2、字符流对应字符数据,它会自动处理与本地字符集之间的转换

3、缓冲流可以提高性能,减少底层API的调用次数来优化IO

Java中,将IO类库分为两种,分为输入和输出两种,所有与输入有关的类继承于InputStresm,所有与输出有关的类继承于OutStream。所有从InputStream或者Reader派生来的类均有read方法,用于读取单个字节或者多个字节数组。同理,所有从OutStream或者Writer派生而来的类均有write方法,用于写单个字节或者数组。下面是字节流、字符流类之间的关系。

InputStream

在这里插入图片描述

OutputStream

在这里插入图片描述

Reader

在这里插入图片描述

Writer

在这里插入图片描述

文件流

文件流的数据读写均是基于文件的操作

  • FileInputStream
  • FileOutputStream
  • FileReader
  • FileWriter

缓冲流

缓冲流的读写均是基于内存的操作

  • BuffferInputStream
  • BuffferOutputStream
  • BuffferReader
  • BuffferWriter

File类

  • java.io.File类:文件和目录的抽象形式,与平台无关
  • File能新建,删除,重命名和目录,但是File不能访问文件内容本身,如果需要访问文件内容本身,则需要使用输入输出流
  • File对象可以作为参数传递给流的构造方法,同样也可以传给File类本身的多参数构造方法
  • File的常见构造方法:
    • public File(String pathname),以pathname为路径创建File对象,可以是绝对路径或者相对路径
    • public File(String parent,String child),以parent为父路径,child为子路径创建File对象
  • 下面是一些File类的方法
import java.io.File;
public class Test13 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		@SuppressWarnings("unused")
		File file=new File("D:\\cam.txt");
		File file1=new File("D:","cam.txt");
		File file2=new File("D:"+File.separator+"cam.txt");
	}
}
import java.io.File;

public class Test13 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		@SuppressWarnings("unused")
		File file=new File("D:\\cam.txt");
		File file1=new File("D:","cam.txt");
		File file2=new File("D:"+File.separator+"cam.txt");
		
		System.out.println(file.getName());//获得文件名称
		System.out.println(file.getPath());//获得文件路径
		
		File file3=new File("Java/Test/Test9.java");
		System.out.println(file3.getPath());//获取的其实是new File时写的路径
		System.out.println(file3.getAbsolutePath());//获取的是当前文件的绝对路径 
		
		System.out.println(file3);//返回new File时的路径
		System.out.println(file3.getAbsoluteFile());//返回一个用当前文件的绝对路径构建的File对象
		System.out.println(file3.getParent());//返回当前文件或者文件夹的父级路径
		
		file.renameTo(new File("D:\\cam1.txt"));//给文件或者文件夹重命名
		
		File file4=new File("D:\\cam1.txt");
		System.out.println(file4.exists());//判断文件是否存在
		
		System.out.println(file4.canWrite());//判断文件是否可写,当设置文件的属性为只读时,返回false
		System.out.println(file4.canRead());//判断文件是否可读
		
		System.out.println(file4.isFile());//判断当前的File对象是否为文件
		System.out.println(file4.isDirectory());//判断Fie对象是否为文件夹或者目录
		
		System.out.println(file4.lastModified());//获取文件最后修改的时间,返回到额是一个毫秒数
		System.out.println(file4.length());//返回文件的长度,单位是字节数
	}

}
import java.io.File;
import java.io.IOException;

public class Test13 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub		
		File file5=new File("D:\\cam2.txt");
		System.out.println(file5.exists());//判断文件是否存在
		if(!file5.exists()) {
			try {
				file5.createNewFile();//创建新的文件
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		//file5.delete()//删除文件
		
		File file6=new File("D:\\a");
		file6.mkdir();//创建单级目录
		
		File file7=new File("D:\\a\\b\\c");
		file7.mkdirs();//创建多级目录
		
		File file8=new File("E:\\Java\\Test\\src");
		String[] Strs=file8.list();//获取的是当前文件夹中子集的名称,包括目录和文件
		for(String str:Strs)
		{
			System.out.println(str);
		}
		
		File[] files=file8.listFiles();//获取的是当前文件夹的子集的File对象,包括目录和文件
		for(File fs:files)
		{
			System.out.println(fs);
		}	
	}
}
import java.io.File;
import java.io.IOException;

public class Test13 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub	
        //递归遍历D:\\a下的文件,包括文件夹和文件
		File file9=new File("D:\\a");
		new Test13().test(file9);
	}
	
	public void test(File file)
	{
		if(file.isFile())
		{
			System.out.println(file.getAbsolutePath()+"是文件");
		}
		else
		{
			System.out.println(file.getAbsolutePath()+"是文件夹");
			File[] fs=file.listFiles();	
			if(fs!=null&& fs.length>0)
			{
				for(File f:fs)
				{
					test(f);//递归操作
				}
			}	
		}
	}
}

Java IO操作

文件流主要分为下面两种情况,准确的说可以包含四种情况,字节/字符流均有输入/输出流,

  • 文件字节/字符输入流:读取硬盘等外部设备数据到程序内存中
  • 文件字节/字符输出流:将程序内存数据输出到硬盘等外部设备中

上面两种均是基于硬盘设备的直接读写,读写速度较慢,为了提高读写速度,java提供了缓冲流的机制进行提高读写速度,先将数据缓冲到内存中,然后再在内存中进行IO操作,并且基于内存的IO操作速度比基于硬盘的IO操作快75000倍。

  • 文件字节/字符缓冲输入流:
  • 文件字节/字符缓冲输出流

PS:无论是文件字节流还是文件字符流,在对输入流进行读操作的时候,均需要确定输入流的文件已经在硬盘存在,否则会出现异常。

文件字节输入流操作

文件字节输入流,需要定义FileInputStream,下面是文件字节输入流的使用方法:

public class TestIo {
    public static void main(String[] args) {
        File file = new File("E:/testIo.txt");
        //如果没有该文件,运行一次先创建该文件
        if(!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println(" is exists");
            //按照1024字节的读写量进行读操作
            byte[] bytes = new byte[1024];
            try {
                FileInputStream fileInputStream = new FileInputStream(file);
                int read = fileInputStream.read(bytes);
                String s = new String(bytes);
                System.out.println(s);
                System.out.println(read);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

如果没有设定一次读出的字节大小,则默认是一个字节,下面是没有设定字节读出大小的使用方法;

FileInputStream fr= null;
try {
    fr = new FileInputStream("E:/testIo.txt");
    BufferedInputStream br=new BufferedInputStream(fr);
    //byte[] b=new byte[10];
    int len=0;
    try {
        len = br.read();
        while(len>0) {
            System.out.print((char)len);
            len = br.read();
        }
        br.close();
        fr.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

文件字节输出流操作

使用文件字节输出流操作需要定义FileOutputStream,文件字节输出流是将内存中的数据写入到外部设备中。下面是文件字节输出流的使用方法:

public static void main(String[] args) {
    try {
        FileOutputStream outputStream = new FileOutputStream("E:/out.txt");//如果该文件不存在,将会自动创建
        String str = "hello world";
        try {
            outputStream.write(str.getBytes());//将数据写到内存中
            outputStream.flush();//将内存中的数据刷写到硬盘
            outputStream.close();//关流操作
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

文件字节流拷贝

基于文件字节输入输出流可以实现文件的拷贝,将文件字节输入流读到的数据写入到文件字节输出流中即可。

public static void main()
{
     try {
         FileInputStream in=new FileInputStream("D:\\cam3.txt");
         FileOutputStream out=new FileOutputStream("D:\\cam4.txt");
         byte[] b=new byte[100];//设定输入流读字节大小是100字节
         int len=0;
         while((len=in.read(b))!=-1)//从输入流中读数据
         {
            out.write(b,0,len);//随后将读到的数据写入到对应的输出流中
         }

         out.flush();//将内存中的输出流刷到外部硬盘中
         out.close();//关闭输出流
         in.close();//最后关闭输入流
     } catch (FileNotFoundException e) {
         e.printStackTrace();
     } catch (IOException e) {
         e.printStackTrace();
    }
}

文件字符流操作

文件字符流操作与文件字节流操作类似,只不过读写操作类不同,文件字符输入流的操作类是FileReader,文件字符输出流的操作类是FileWriter。

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test1 {
    public  static void main(String[] args)
    {
        //文件字符输入流
        try {
            Test1.testFileReader("D:\\cam3.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }

        //文件字符输出流
        Test1.testFileWriter("hello world","D:\\stitch.txt");

        //文件字符流复制
        try {
            Test1.copyFile("D:\\cam5.txt","D:\\cam6.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 文件字符输入流
     * @param path
     * @throws IOException
     */

    public static void testFileReader(String path) throws IOException {
        try {
            FileReader fr=new FileReader(path);
            char[] c=new char[5];
            int len=0;
            while((len=fr.read(c))!=-1)
            {
                System.out.println(new String(c,0,len));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 文件字符输出流
     * @param text
     * @param outPath
     */

    public static void testFileWriter(String text,String outPath)
    {
        try {
            FileWriter fw=new FileWriter(outPath);
            fw.write(text);
            fw.flush();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 文件字符流的复制
     * @param inPath
     * @param outPath
     * @throws IOException
     */
    public static void copyFile(String inPath,String outPath) throws IOException {
        try {
            FileReader fr=new FileReader(inPath);
            FileWriter fw=new FileWriter(outPath);

            char[] c=new char[100];
            int len=0;
            while((len=fr.read(c))!=-1)
            {
                fw.write(c,0,len);
            }

            fw.close();
            fr.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

文件字符/字节缓冲流

为了提高与硬盘之间读写数据的速度,java提供了缓冲流机制,以提高数据的读写速度。

  • 文件字节缓冲流:BufferedInputStremBufferedOutputStream对应的分别是FileInputStreamFileOutputStream
  • 文件字符缓冲流:BufferedReaderBufferedWriter对应的分别是FileReaderFileWriter

文件字节缓冲流的使用方法如下:

//缓冲字节输入流用法:
File file = new File("E:\\untitled\\src\\text.txt");
FileInputStream inputStream = new FileInputStream(file);
//定义缓冲字节输入流
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
byte[] bytes = new byte[10];
int len = bufferedInputStream.read(bytes);//将数据读出到定义的bytes字节数组中

//缓冲字节输入流用法:
File file = new File("E:\\untitled\\src\\text1.txt");
FileOutputStream outputStream = new FileOutputStream(file);
//定义缓冲字节输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
String str = "hello world";
bufferedOutputStream.write(str.getBytes());//将数据写到内存
bufferedOutputStream.flush();//刷到硬盘
//关闭流,本着最早开的最晚关,最晚开的最早关
bufferedOutputStream.close();
outputStream.close();

//缓冲字符输入流用法:
FileReader fileReader=new FileReader("E:\\untitled\\src\\text.txt");
//定义缓冲字符输入流
BufferedReader br=new BufferedReader(fileReader);
char[] c=new char[1024];
int len = br.read(c);

//缓冲字符输出流用法:
FileWriter fw=new FileWriter("E:\\untitled\\src\\text3.txt");
//定义缓冲字符输出流
BufferedWriter bw=new BufferedWriter(fw);//定义缓冲字符输出流
String  str="hello world";
bw.write(str.getBytes());将数据写到内存
bw.flush();//刷到硬盘
//关闭流,本着最早开的最晚关,最晚开的最早关
bw.close();
fw.close();

下面是具体的使用方法:

import java.io.*;

public class Test3 {
    public static void main(String[] args)
    {
        try {
            Test3.testBufferReader();
            Test3.testBufferWriter();
            Test3.copyFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 缓冲字符输入流
     * @throws IOException
     */
    public static void testBufferReader() throws IOException {
        FileReader fr=new FileReader("E:\\untitled\\src\\text.txt");
        BufferedReader br=new BufferedReader(fr);
        char[] c=new char[1024];
        int len=0;
        while((len=br.read(c))!=-1)
        {
            System.out.println(new String(c,0,len));
        }
        br.close();
        fr.close();
    }

    /**
     * 缓冲字符输出流
     * @throws IOException
     */
    public static void testBufferWriter() throws IOException {
        FileWriter fw=new FileWriter("E:\\untitled\\src\\text3.txt");
        BufferedWriter bw=new BufferedWriter(fw);
        String  str="hello world";
        bw.write(str);
        bw.flush();
        bw.close();
        fw.close();
    }

    /**
     * 缓冲字符流的复制
     * @throws IOException
     */
    public static void copyFile() throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("E:\\untitled\\src\\text3.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("E:\\untitled\\src\\text4.txt"));
        char[] c=new char[1024];
        int len=0;
        while((len=br.read(c))!=-1)
        {
            bw.write(c,0,len);
        }

        bw.flush();//刷到硬盘中
        bw.close();
        br.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值