Java IO之文件输入、输出流

时间:2023-02-26 17:25:38

首先,我们要知道的是,文件的输入、输出都是相对于内存而言的,输入即从外存读入到内存,输出则是从内存写入到外存

1.FileInputStream类

称为文件输入流,继承于InputStream类,是进行文件读操作的最基本类。它的作用是将文件中的数据输入到内存中,我们可以利用它来读文件

由于它属于字节流,因此在读取Unicode字符(如中文)的文件时可能会出现问题

FileInputStream类的构造方法有3种重载方式,以下是常用的几种:

1.FileInputStream(File file) throws FileNotFoundException,使用File对象创建文件输入流对象,如果文件打开失败,将抛出异常

2.FileInputStream(String name) throws FileNotFoundException,使用文件名或路径创建文件输入流对象,如果文件打开失败,将抛出异常

Java  IO之文件输入、输出流

这是输入流类中的从外存中读取文件的方法,记得读完后一定要及时关闭,就像是水龙头一样。

方法摘要
 int available()
          返回可以从此输入流读取(或跳过)、且不受此输入流接下来的方法调用阻塞的估计字节数。
 void close()
          关闭此输入流并释放与该流关联的所有系统资源。
 void mark(int readlimit)
          参见 InputStreammark 方法的常规协定。
 boolean markSupported()
          测试此输入流是否支持 markreset 方法。
 int read()
          参见 InputStreamread 方法的常规协定。
 int read(byte[] b, int off, int len)
          从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。
 void reset()
          参见 InputStreamreset 方法的常规协定。
 long skip(long n)
          参见 InputStreamskip 方法的常规协定。

2.FileOutputStream类

称为文件输出流,继承于OutputStream类,是进行文件写操作的最基本类,它的作用是将内存中的数据输出到文件中,我们可以利用它来写文件

FileOutputStream类的构造方法有5种重载方式,以下是常用的几种:

FileOutputStream(File file) throws FileNotFoundException 使用File对象创建文件输出流对象,如果文件打开失败,将抛出异常

FileOutputStream(File file, boolean append) throws FileNotFoundException 使用File对象创建文件输出流对象,并由参数append指定是否追加文件内容,true为追加,false为不追加,异常情况同上

FileOutputStream(String name)throws FileNotFoundException  直接使用文件名或路径创建文件输出流对象,异常情况同上

FileOutputStream(String name, boolean append) throws FileNotFoundException 直接使用文件名或路径创建文件输出流对象,并由参数append指定是否追加,异常情况同上

方法摘要
 void flush()
          刷新此缓冲的输出流。
 void write(byte[] b, int off, int len)
          将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。
 void write(int b)
          将指定的字节写入此缓冲的输出流。

这是文件输出流类封装的方法。


下面我用一个简单的复制粘贴文件的例子,来简单的介绍一下read和write的用法,注意其中的一些细节问题。

还有创建流对象的方法

public class FileCopy {
/**
* 对文件进行复制粘贴
*
* 分两步:从磁盘读取目标文件 在相应路径下写入磁盘
* @param srcPath
* 文件的源路径(包含文件名)
* @param destPath
* 文件的写入的母的路径(包含文件名) 注意:这两个文件的扩展名要相同
* @throws IOException
*/
public static void fileCopyByByte(String srcPath,String destPath) throws IOException {
//根据srcPath创建一个文件输入流对象 来读取文件
FileInputStream fis = new FileInputStream(srcPath);
//根据destPath创建一个文件输出流对象 来写文件
FileOutputStream fos= new FileOutputStream(destPath);
//从文件中一个一个字节地读(读一个少一个)
int i = fis.read();//返回值是对应字符的ascII 当返回值是-1时,表示文件已经读完
while(i!=-1){
//读到就写 读一个写一个
fos.write(i);
i = fis.read();//读写完一个就继续下一个
}
System.out.println("文件复制完毕!");
//及时关闭流
fis.close();
fos.close();
}

/**
* 每次一段一段读写数据,效率高些,因为内存空间有限,所以遇到大的文件时不能整个文件读取,要分段
* @param srcPath 源路径
* @param destPath 写入的目的路径
* @throws IOException
*/
public static void fileCopyByPiece(String srcPath,String destPath) throws IOException {
//根据srcPath创建一个文件输入流对象 来读取文件
FileInputStream fis = new FileInputStream(srcPath);
//根据destPath创建一个文件输出流对象 来写文件
FileOutputStream fos= new FileOutputStream(destPath);
//创建一个缓冲区(容器),暂时的存放数据
byte [] buf = new byte[1024];//这相当于是一个缓冲区,因为读入的数据暂时存放在数组中
//从文件中读取数据,以字节数组的长度为单位去读写
int i =fis.read(buf);//数据暂时存放在数组中 -1表示已经读完 注意:注意:这里的i是指(数组从磁盘)每次(以数组为单位)读到的有效长度
//读是只会读有效的,所以不必担心多读,那方法是指定读多少用的
while(i!=-1){
//读到就写入磁盘
//fos.write(buf);//由于本方法到最后一次时,若不是1024即数组长度的整数倍,读的有效数据就不会再次填满数组,而写入的时候还是会写入整个数组长度的
//这样的话,会造成黏贴后的文件比原文件多了无效的数据,久而久之就会无形的消耗很多磁盘的空间
//改进
fos.write(buf, 0, i);//参数解释,数组名,偏移量(每次写入的位置,即从数组的那个下标开始写入),写入的长度(即要写入的有效长度)
i = fis.read(buf);//写完就继续读

}
System.out.println("复制粘贴OK!");
//及时关闭流
fis.close();
fos.close();
}

// 主函数 程序入口
public static void main(String[] args) throws IOException {
String srcPath = "E:\\期末题选10分.ppt";
String destPath ="E:\\复制.ppt";
FileCopy fc = new FileCopy();
//fc.fileCopyByByte(srcPath,destPath);
fc.fileCopyByPiece(srcPath,destPath);

}
}
最后:注意小心使用复制粘贴,注意细节,别把外存的重要数据整坏了,或者把外存填满了!!!