本节主要介绍下面内容
文件的复制
目录
用FileInputStream复制
用BufferedInputStream复制
文件的加密:
用FileInputStream复制
文件的拷贝需要将文件读入到内存中,再将文件从内存中写入到硬盘中,
需要用文件输入流FileInputStream读取文件,
每次读取一个byte数组的内容,
用文件输出流FileOutputStream将byte数组写出到文件
画个图
示例:用FileInputStream和FileOutputStream拷贝文件
import java.io.*;
public class FileCopy {
public static void main(String[] args){
try( FileInputStream fis=new FileInputStream("G:\\x269all.rmvb") ;
FileOutputStream fos=new FileOutputStream("G:\\x270.rmvb");
) {
byte [] bytes=new byte[1024];
int temp;
while((temp=fis.read(bytes))!=-1){
fos.write(bytes,0,temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
用BufferedInputStream复制
用BufferedInputStream和BufferedOutputStream拷贝文件
看下缓冲输入流BufferedInputStream的部分源码:
BufferedInputStream工作工程,在自身创建一个byte数组,调用read方法时,先将内容读取到byte数组,再从byte数组中读取,当byte数组的元素被读取完的时候,会调用fill方法填充本身的byte数组,关闭BufferedInputStream时自动关闭作为参数的InputStream对象
public class BufferedInputStream extends FilterInputStream {
private static int DEFAULT_BUFFER_SIZE = 8192;
//构造方法,调用带两个参数的构造方法,默认缓冲大小为8192字节,8M
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
//带两个参数的构造方法,内部利用了一个长为8192的byte数组
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
...
}
BufferOutputStream部分源码
工作原理:将内容写到BufferedOutputStream中的byte数组,再从byte数组中访问,关闭BufferedOutputStream时,自动关闭作为参数的OutputStream对象
public class BufferedOutputStream extends FilterOutputStream {
protected byte buf[];
protected int count;
public BufferedOutputStream(OutputStream out) {
this(out, 8192);
}
//构造函数,创建8192字节大小的byte数组,作为缓存区
public BufferedOutputStream(OutputStream out, int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
//刷新缓存,将缓存内容通过OutputStream写入到硬盘或者其他地方,out是父类中属性,类型是OutputStream
private void flushBuffer() throws IOException {
if (count > 0) {
//out值得是OutputStream
out.write(buf, 0, count);
count = 0;
}
}
@Override
public synchronized void write(int b) throws IOException {
if (count >= buf.length) {
flushBuffer();
}
buf[count++] = (byte)b;
}
//写数组,还是通过OutputStream的写方法完成
@Override
public synchronized void write(byte b[], int off, int len) throws IOException {
if (len >= buf.length) {
/* If the request length exceeds the size of the output buffer,
flush the output buffer and then write the data directly.
In this way buffered streams will cascade harmlessly. */
flushBuffer();
out.write(b, off, len);
return;
}
if (len > buf.length - count) {
flushBuffer();
}
System.arraycopy(b, off, buf, count, len);
count += len;
}
@Override
public synchronized void flush() throws IOException {
flushBuffer();
out.flush();
}
}
复制过程:
可以看到,BufferedInputStream的构造方法要传入InputStream流对象,然后创建一个长8192的byte数组(8k),每次缓冲这么长的数组
说明BufferedInputStream和BufferedOutputStream也可以用来拷贝文件,过程是先从FileInputStream中每次读取8k读到输入缓存区,再从输入缓存去写到输出缓存区,再从输出缓存区通过FileOutputStream每次写8k写入到硬盘,减少了硬盘的读写次数,避免了硬盘的频繁访问,效率会高
画个图:
代码示例:
package io01;
import java.io.*;
public class FileCopy02 {
public static void main(String[] args){
try(
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("G:\\x269all.rmvb"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("G:\\x256.rmvb"));
) {
int temp;
while ((temp=bis.read())!=-1) {
//从硬盘写入到输入缓存区,再从输入缓存区快速写入到输出缓存区,再写入到硬盘
bos.write(temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
既然FileInputStream和FileOutputStream可以完成复制,为什么还要用BufferedInputStream和BufferedOutputStream?
因为先将多个字节写入到内存中的缓存区,可以减少对硬盘io的访问,提高效率,写入到硬盘的时候同理
文件的加密:
前面我博客简单说过两个整数a和b,a异或b两次得到的还是a,以此可以做两个整数交换,也可以做简单的加密解密
示例:
package io01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCode {
public static void main(String[] args){
try (
FileInputStream fis=new FileInputStream("G:\\辩证法.jpg");
FileOutputStream fos=new FileOutputStream("G:\\39.jpg");
){
int temp;
while((temp=fis.read())!=-1){
fos.write(temp^89);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package io01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileDecode {
public static void main(String[] args){
try (
FileInputStream fis=new FileInputStream("G:\\39.jpg");
FileOutputStream fos=new FileOutputStream("G:\\40.jpg");
){
int temp;
while((temp=fis.read())!=-1){
fos.write((temp)^89);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
| Chinese (Simplified)English |
| Chinese (Simplified)English |
|
|
|
|
|
Text-to-speech function is limited to 200 characters