JAVA读取文件的几大方法(一)以及怎么实现复制文件功能
在JAVA中,一个可以读取文件的对象叫做输入流,一个可以写入文件的对象叫输出流。在JAVA中可以字节的形式直接输入输出文件,与之相关的是抽象类InputStream,和OutputStream
下面将介绍上这两个抽象类的常用实现子类
文件输入流:FileInputStream
构造方法FileInputStream(File file)
FileInputStream(String name)
即用一个文件对象,或者一个保存了文件地址的字符串来进行初始化。
需要注意的是,要读取的文件必须存在,否则会报错
int read() 读取一个字节文件,如果已经是文件末尾,则返回-1
int read(byte[] b) 读取一个字节数组
我们知道read方法是以字节形式读取文件的那
read方法返回一个int型数据而不直接返byte型数据看似不符合逻辑。JAVA开发人员为什么要这样写呢?
因为它要将字节型数据转换为整形数据。为什么要转换成整形数据呢?
因为他要用返回-1来判断是否达到文件末尾。
那-1一定可以表示文件末尾吗,文件中的数据不会出现-1吗?答案是不会出现,因为将byte型数据
转换为int型的时候是将byte数据左边填0,所以一定会得到一个正的整数。
int available() 得到流中剩余的字节数
注意每次调用一个read方法 流中的数据都会减少。
但是如果文件大小超出了 流能读的大小 将流中的数据读完之后会怎样呢
答案: 跟文件格式有关,读GHO文件时每读一个就会从文件中输入到流中一个字节 ,ZIP格式的则不会没读一个输入一个
那么说到这来我们肯定会关心流能存的最大大小是多少呢?其实我们注意观察很容易得到一个最大范围:此方法返回的是int 型数据,那么显然它能存的数据必然小于即int 范围, 既2的31次方 2GB,我们可以大胆猜想它能存的最大数据就是2GB,但是有个看似合理的推论是不够的,那我们要怎样得到切确的数据呢?只有自己测试下了。我测试的结果是它能存的最大数据确实是2的31次方字节即2GB
缓冲字节输入流:BufferedInputStream
将输入流用缓冲字节输入流包装,能够加快读入速度
文件输出流:FileOutputStream
write(int b) 写出一个字节 这里为什么参数是int型数据呢,因为其实写出的是一个ASCLL码
例如write(97) 那么用记事本打开文件看到的是一个a
fos.write(-42);
fos.write(-48);
那其实写出的是 “中字”(汉字的ASCLL码是负数,且一个汉字占两字节)
write(byte[] b)
写出一个字节数组
需要注意的是在write方法后一再调用输出流的flush();方法
因为内存的读写速度远远大于硬盘的读写速度,
所以可能会有残留在内存缓存中的数据没有写到硬盘中去,
所以要推送缓存数据到硬盘。
缓冲字节输出流
BufferedOutputStream
将输出流用缓冲字节输入流包装,能够加快读入速度
下面贴一个用字节输入输出流实现文件复制的程序
package date0523_文件操作; /** * 该程序用字节输入输出流实现了文字复制功能 */ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.util.Date; public class Project { public static void main(String[] args) { long start=System.currentTimeMillis(); if(copyFile("abc.txt","bb.txt")) System.out.println("复制成功"); long end=System.currentTimeMillis(); System.out.println("所用时间:"+(end-start)+"ms"); } /** * 实现文件复制功能 * @param sPath 源文件地址 * @param dPath 拷贝文件地址 * @return 是否复制成功 */ public static boolean copyFile(String sPath,String dPath) { File sFile=new File(sPath); File dFile=new File(dPath); FileInputStream fis; try { fis = new FileInputStream(sFile); System.out.println(sFile.length()); BufferedInputStream bis=new BufferedInputStream(fis); FileOutputStream fos=new FileOutputStream(dFile); BufferedOutputStream bos=new BufferedOutputStream(fos); int t=bis.read(); while(t!=-1) { byte b=(byte)t; bos.write(b); t=bis.read(); } bos.flush(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } }
多谢指导
如果是要复制大一点的文件的话,是不能开辟那么大的数组的