IO
1. IO 流体系
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | InputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream |
1.1 File
java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源。
- File既可以表示一个文件(.doc .xls .mp3 .avi .jpg .dat),也可以表示一个文件目录!
- File类的对象是与平台无关的。
- File类针对于文件或文件目录,只能进行新建、删除、重命名、上层目录等等的操作。如果涉及到访问文件的内容,File是无能为力的,只能使用IO流下提供的相应的输入输出流来实现。
2. FileInputStream、FileOutputStream
继承于InputStream类,这是一个文件输入流,进行文件读操作的最基本的类
读取字节流文件,可以读写英文字符
复制文件
private static void copyFileUsingFileStreams(File source, File dest)
throws IOException {
FileInputStream input = null;
FileOutputStream output = null;
try {
input = new FileInputStream(source);
output = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) != -1) {
output.write(buf, 0, bytesRead);
}
} finally {
input.close();
output.close();
}
}
3. BufferedInputStream、BufferOutputStream
区别:
不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节(默认8k),但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
使用缓冲输出流和缓冲输入流实现文件的复制
public static void main(String[] args){
/**
* 1.先将文件中的内容读入到缓冲输入流中
* 2.将输入流中的数据通过缓冲输出流写入到目标文件中
* 3.关闭输入流和输出流
*/
try {
long begin=System.currentTimeMillis();
FileInputStream fis=new FileInputStream("BISDemo.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
FileOutputStream fos=new FileOutputStream("BOSDemo2.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
int size=0;
byte[] b=new byte[10240];
while((size=bis.read(b))!=-1){
bos.write(b, 0, size);
}
//刷新此缓冲的输出流,保证数据全部都能写出
bos.flush();
bis.close();//注意使用try-catch-finally
bos.close();
long end=System.currentTimeMillis();
} catch (Exception e) {
e.printStackTrace();
}
}
4. BufferedReader、BufferedWriter
以行为单位读取文件,常用于读面向行的格式化文件
BufferedReader reader = new BufferedReader(new FileReader(file));
String tempString = null;
int line = 1;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
System.out.println(tempString);
line++;
}
reader.close();
file.close();// 此处用try-catch 好一些
————————————————
public void fileOutput(String content) throws IOException {
//String content="hahahhaha哈哈哈哈";
File file = new File("D:\\newSe.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write(content);
bw.flush();
bw.close();
file.close();
}// 此处用try-catch 好一些
直接使用FileReader读取一个包含中文字符的文件,将字符输入流放到BufferedReader中,通过BufferedReader读取出来
的中文字符串乱码.
分析:文件流读取时使用的编码方式和文件本身编码方式不同,造成读取出来文件乱码.
解决办法:读取文件时指定读取文件的编码方式.
InputStreamReader isr = new InputStreamReader(new FileInputStream(new File(filePath)), "UTF-8");
BufferedReader br = new BufferedReader(isr);
使用FileInputStream类读取文件流,BufferedReader构造方法只能接收字符流,利用InputStreamReader将字节流转化为字符流,同时指定文件流的编码方式,将字符流放到 BufferedReader中,进行操作,中文读取乱码问题解决.
5. InputStreamReader、InputStreamWriter
以字符为单位读取文件,常用于读文本,数字等类型的文件 ,不常用
Reader reader = new InputStreamReader(new FileInputStream(myFile));
// 一次读一个字节
int tempchar;
while ((tempchar = reader.read()) != -1) {
// 对于windows下,\r\n这两个字符在一起时,表示一个换行。
// 但如果这两个字符分开显示时,会换两次行。
// 因此,屏蔽掉\r,或者屏蔽\n。否则,将会多出很多空行。
if (((char) tempchar) != '\r') {
System.out.print((char) tempchar);
}
}
reader.close();
// 一次读多个字节
char[] tempchars = new char[30];
int charread = 0;
// 读入多个字符到字符数组中,charread为一次读取字符数
while ((charread = reader.read(tempchars)) != -1) {
// 同样屏蔽掉\r不显示
if ((charread == tempchars.length) && (tempchars[tempchars.length - 1] != '\r')) {
System.out.print(tempchars);
} else {
for (int i = 0; i < charread; i++) {
if (tempchars[i] == '\r') {
continue;
} else {
System.out.print(tempchars[i]);
}
}
}
}
6.java复制文件的4种方式
使用FileStreams复制
使用FileChannel复制
使用Commons IO复制
使用Java7的Files类复制
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import org.apache.commons.io.FileUtils;
public class CopyFilesExample {
public static void main(String[] args) throws InterruptedException,
IOException {
File source = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile1.txt");
File dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile1.txt");
// copy file using FileStreamslong start = System.nanoTime();
long end;
copyFileUsingFileStreams(source, dest);
System.out.println("Time taken by FileStreams Copy = "
+ (System.nanoTime() - start));
// copy files using java.nio.FileChannelsource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile2.txt");
dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile2.txt");
start = System.nanoTime();
copyFileUsingFileChannels(source, dest);
end = System.nanoTime();
System.out.println("Time taken by FileChannels Copy = " + (end - start));
// copy file using Java 7 Files classsource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile3.txt");
dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile3.txt");
start = System.nanoTime();
copyFileUsingJava7Files(source, dest);
end = System.nanoTime();
System.out.println("Time taken by Java7 Files Copy = " + (end - start));
// copy files using apache commons iosource = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile4.txt");
dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile4.txt");
start = System.nanoTime();
copyFileUsingApacheCommonsIO(source, dest);
end = System.nanoTime();
System.out.println("Time taken by Apache Commons IO Copy = "
+ (end - start));
}
private static void copyFileUsingFileStreams(File source, File dest)
throws IOException {
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(source);
output = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
} finally {
input.close();
output.close();
}
}
private static void copyFileUsingFileChannels(File source, File dest)
throws IOException {
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
inputChannel = new FileInputStream(source).getChannel();
outputChannel = new FileOutputStream(dest).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} finally {
inputChannel.close();
outputChannel.close();
}
}
private static void copyFileUsingJava7Files(File source, File dest)
throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
private static void copyFileUsingApacheCommonsIO(File source, File dest)
throws IOException {
FileUtils.copyFile(source, dest);
}
}
输出
Time taken by FileStreams Copy = 127572360
Time taken by FileChannels Copy = 10449963
Time taken by Java7 Files Copy = 10808333
Time taken by Apache Commons IO Copy = 17971677
可以看到FileChannels拷贝大文件是最好的方法。如果处理更大的文件,会有一个更大的速度差。-----------------------------------------------------------