`
人生难得糊涂
  • 浏览: 114503 次
社区版块
存档分类
最新评论

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;
	}

}

 

 

0
0
分享到:
评论
4 楼 人生难得糊涂 2014-05-26  
I白I 写道
bis.read(); 这里为什么不读一个字节数组,这样一个一个字节读 效率还不低死

如果是要复制大一点的文件的话,是不能开辟那么大的数组的
3 楼 人生难得糊涂 2014-05-26  
youjianbo_han_87 写道
大文件Copy应该用Nio里面的直接文件读取,这样快很多,你可以试试。

多谢指导
2 楼 I白I 2014-05-26  
bis.read(); 这里为什么不读一个字节数组,这样一个一个字节读 效率还不低死
1 楼 youjianbo_han_87 2014-05-26  
大文件Copy应该用Nio里面的直接文件读取,这样快很多,你可以试试。

相关推荐

Global site tag (gtag.js) - Google Analytics