JavaSE FileInputStream(文件字节输入流)

FileInputStream(文件字节输入流)

一、java.io.FileInputStream

  • 文件字节输入流,任何类型的文件都可以采用这个流来读
  • 以字节的方式,完成输入的操作,完成读的操作(硬盘—> 内存)
  • 读取数据的原理(硬盘—>内存)
    Java程序–>JVM(Java虚拟机)–>OS(操作系统)–>OS调用读取数据的方法–>读取文件
  • 字节输入流的使用步骤
  1. 创建一个FileInputStream对象,构造方法中绑定要读取的数据源
  2. 调用FileInputStream对象中的方法read,读取文件
  3. 释放资源(流使用会占用一定的内存,使用完毕后要把内存清空,提高程序的效率)

1. 测试用例初步(开发不用)

  • 在D:\Test下创建temp文件,文件内容:abcdef
  • 读取字节:read方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			// 创建文件字节输入流对象
			// 文件路径:D:\Test\temp (自动把\编程\\,因为java中\表示转义)
			// FileInputStream fis = new FileInputStream("D:\\Test\\temp");
			// 写成/也可以
			fis = new FileInputStream("D:/Test/temp"); // 编译时异常

			// 开始读(如果已达到文件末尾,则返回-1)
			int readData = fis.read(); // read()方法的返回值是:读取到的“字节”本身
			System.out.println(readData); // 97

			readData = fis.read();
			System.out.println(readData); // 98

			readData = fis.read();
			System.out.println(readData); // 99

			readData = fis.read();
			System.out.println(readData); // 100

			readData = fis.read();
			System.out.println(readData); // 101

			readData = fis.read();
			System.out.println(readData); // 102

			// 达到文件末尾,再读的时候读取不到任何数据,返回-1
			readData = fis.read();
			System.out.println(readData); // -1
			
			readData = fis.read();
			System.out.println(readData); // -1

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 在finally语句块当中确保流关闭
			if (fis != null) { // 避免空指针异常
				// 关闭流的前提是:流不是空,流是null的时候没必要关闭
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
  • 对以上程序进行改进,采用循环的方式
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
	public static void main(String[] args) {
		/**
		 * 在D:\Test下创建temp文件,文件内容:abcdef
		 * 此程序和以上程序一次读取一个字节byte,这样内存和硬盘交互太频繁,基本上时间/资源都耗费在交互上面了
		 */
		FileInputStream fis = null;
        try {
            fis = new FileInputStream("D:\\Test\\temp");

            /*while(true) {
                int readData = fis.read();
                if(readData == -1) {
                    break;
                }
                System.out.println(readData);
            }*/

            // 改进while循环
            int readData = 0;
            while((readData = fis.read()) != -1){
                System.out.println(readData); // 97 98 99 100 101 102
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
	}
}
  • 以上两个程序一次读取一个字节byte,这样内存和硬盘交互太频繁,基本上时间/资源都耗费在交互上面了
  • 对以上两个程序进行改进,一次读取多个字节

2. 测试用例改进

  • 使用字节数组读取int read(byte[] bytes),一次最多读取 bytes.length 个字节,即往byte[]数组当中读,减少硬盘和内存的交互,提高程序的执行效率,读取到末尾时,返回-1
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
	public static void main(String[] args) {
		/**
		 * 在D:\Test下创建temp文件,文件内容:abcdef
		 * 使用int read(byte[] bytes)
		 */
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("D:\\Test\\temp");

			// 开始读,采用byte数组,一次读取多个字节,最多读取“数组.length”个字节
			// 准备一个4长度的byte数组,一次最多读取4个字节
			byte[] bytes = new byte[4];
			int readCount = fis.read(bytes); // 这个方法的返回值是:读取到的字节数量(不是字节本身)
			System.out.println(readCount); // 4,即第一次读到了4个字节
			// 将字节数组全部转换成字符串
			// System.out.println(new String(bytes)); // abcd
			// 不应该全部都转换,应该是读取了多少个字节,转换多少个
			System.out.println(new String(bytes, 0, readCount)); // abcd

			readCount = fis.read(bytes); // 第二次只能读取到2个字节
			System.out.println(readCount); // 2,即第二次读到了2个字节
			// 将字节数组全部转换成字符串
			// System.out.println(new String(bytes)); // efcd
			// 不应该全部都转换,应该是读取了多少个字节,转换多少个
			System.out.println(new String(bytes, 0, readCount)); // ef

			readCount = fis.read(bytes); // 1个字节都没有读取到则返回-1
			System.out.println(readCount); // -1

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

3. 测试用例最终(掌握)

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("D:\\Test\\temp");
			// 准备一个byte数组
			byte[] bytes = new byte[4];

			/*while(true) {
        	int readCount = fis.read(bytes);
        	if(readCount == -1) {
        		break;
        	}
        	// 把byte数组转换成字符串,读到多少个转换多少个
            System.out.print(new String(bytes, 0, readCount));
        }*/
			
			int readCount = 0;
			while ((readCount = fis.read(bytes)) != -1) {
				System.out.print(new String(bytes, 0, readCount));
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

二、FileInputStream类的其它常用方法

1. int available()

  • 返回流当中剩余的没有读到的字节数量
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
	public static void main(String[] args) {
		/**
		 * int available():返回流当中剩余的没有读到的字节数量
		 */
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("D:/Test/temp");
			System.out.println("总字节数量:" + fis.available()); // 6
			// 读1个字节
			 int readByte = fis.read();
			 System.out.println("剩下多少个字节没有读:" + fis.available()); // 5
			 byte[] bytes = new byte[fis.available()]; // 这种方式不太适合太大的文件,因为byte[]数组不能太大
			// 不需要循环了,直接读一次就行了
			 int readCount = fis.read(bytes); // 6
			 System.out.println(new String(bytes)); // bcdef

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

2. long skip(long n)

  • 跳过几个字节不读
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
	public static void main(String[] args) {
		/**
		 * long skip(long n):跳过几个字节不读
		 */
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("D:/Test/temp");
			// skip()方法跳过几个字节不读取
			fis.skip(4);
			System.out.println(fis.read()); // 101
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jayco江柯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值