java中的文件输入输出流,实现复制粘贴

java中文件输入输出流是FileInputStream和FileOutputStream,文件输入流从文件系统中的某个文件中获得输入字节,然后可以用输出流将数据写入文件中。

首先创建两个流的对象:

FileInputStream的构造方法有三种重载方式,常用的是FileInputStream(File file)和FileInputStream(String path),前者需要传递的是一个File对象,输入流将直接与这个文件相关联,获取这个文件的数据;后者需要传递的参数是文件的路径名,输入流则将关联此路径下的文件。

FileOutputStream的构造方法有五种重载形式,常用的是FileOutputStream(File file),FileOutputStream(File file, boolean append),FileOutputStream(String name)和FileOutputStream(String name, boolean append),第一个和第三个与FileInputStream相同,都是将文件或路径对应的文件与输出流相关联,其他两种的参数多了一个布尔型的append,是指定输出流是否追加的,如果为true,则将字节写入文件末尾处,而不是写入文件开始处 ,为false则是重新输出到文件中,默认为true。

无论是创建FileInputStream还是创建FileOutputStream时,如果指定文件不存在,或者它是一个目录,而不是一个常规文件,抑或因为其他某些原因而无法打开进行读取,则抛出 FileNotFoundException异常,所以创建这两类对象时,应该处理这些异常,一般将它们放到try/catch块中进行捕获。

进行文件的读写操作时首先是关联好读取的文件和要写出的文件,接下来就需要调用文件输入输出流中的几个重要的方法,输入流中的read()方法读取数据,输出流的write()方法输出数据,调用这两个方法时需要进行异常捕获IO异常。

read()有几种重载方式,其中常用的有int read()和int read(byte[] bytes),前者是一次读取一个字节,读取的数据作为返回值返回,如果读到文件末尾则返回-1,后者是从此输入流中将最多bytes.length 个字节的数据读入一个 byte 数组中,返回读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回-1。这如同文件是一缸水,前者是一滴一滴去取,后者是用一个容器去取,显然前者更安全,后者更快速。

同样的write()也有void write(int i)和void write(byte[] bytes)两种重载,前者是将指定字节写入此文件输出流,后者是将bytes.length 个字节从指定 byte 数组写入此文件输出流中。 

另外文件输入流和文件输出流中都有一个close()的方法,这个方法用来关闭流对象并释放与此流有关的所有系统资源,所以每次在使用完流对象后应注意分别调用文件输入流和文件输出流的close()方法,此方法有可能抛异常,必须进行捕捉。

使用以上的内容我们可以实现简单的文件复制粘贴。

复制粘贴的思路是:

1、创建输出流对象,并与需要复制的文件相关联。因为重载方法有几种,所以可以按需要选择。

如:

FileInputStream fis = new FileInputStream("C:\\Users\\lenovo\\Desktop\\新建文本文档.txt");
或:

File file = new File("C:\\Users\\lenovo\\Desktop\\新建文本文档.txt");
FileInputStream fis = new FileInputStream(file);
2、创建输出流对象,并与需要粘贴的文件相关联。同样也可以有几种写法。

如:

FileOutputStream fos = new FileOutputStream("C:\\Users\\lenovo\\Desktop\\123.txt");
或:

File file = new File("C:\\Users\\lenovo\\Desktop\\123.txt");
FileOnputStream fos = new FileOnputStream(file);

2、读取文件并输出

这里可以用一个字节一个字节读取写出或用字节数组来读写。

//写法一:一个字节一个字节读取文件并输出
int i = fis.read();
while(i!=-1)
{
	fos.write(i);
	i = fis.read();
}

//写法二:用字节数组来作为缓冲区进行读写
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
fos.write(bytes);
需要注意的是调用read()方法时,调用一次减少一个字节,如果写成

while(fis.read()!=-1)
{
fos.write(fis.read());
}
则会出现错误,因为在while括号里面读一次后如果文件没有结束进入循环则写出的是文件的下一个数据(因为刚才while括号里面读了一个,就要进行下一个)

上面的写法二可以看到字节数组的参数这个地方用的是available(),这个方法返回的是下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数,那上面的用法就是一次读完文件所有的数据,放在bytes里面,也就是上面说的一次性把水缸里面的水都取出来,这种方法一般不推荐用,因为水缸的水是固定的,但在其他一些情况下,像两个人打电话说话的人像输入流,听的人像输出流,这时调用available()方法就是要将对方的话全部取出来,一次性听完,然而你并不知道对方有多少话要说。(这种情况在网络通讯那一块会涉及),这时就不能使用这种方法了,所以bytes的大小应该设置一个合适的值,水缸的水一盆一盆来取。

比如可以将fis.available()改成1024,这样取的时候就是1024的字节来取,但是这时又有一个问题了,当要复制的文件大小不是1024个字节的整数倍的时候,调用write()方法还是会按bytes的长度写入1024个字节(用盆取水,最后缸里的水不足一盆还是认为取了一盆),所以粘贴后的文件往往大于复制的文件,要解决这个办法需要用read()和write()的第三个重载方式int read(byte[ ] b, int off, int len)和voidwrite(byte[ ] b, int off, int len)

byte[] bytes = new byte[1024];
int i = fis.read(bytes,0,1024);
while(i!=-1)
{
	fos.write(bytes,0,i);
	i = fis.read(bytes,0,1024);
}
最后再调用fis.close()和fos.close()关闭流,这样就可以实现简单的文件复制了。





你可能感兴趣的:(java)