所谓IO,也就是Input与Output的缩写。在java中,IO涉及的范围比较大,这里主要讨论针对文件内容的读写,其他知识点将放置后续章节。
对于文件内容的操作主要分为两大类,分别是:
- 字符流
- 字节流
其中,字符流有两个抽象类:Writer 、 Reader。
其对应子类FileWriter和FileReader可实现文件的读写操作,
BufferedWriter和BufferedReader能够提供缓冲区功能,用以提高效率。
同样,字节流也有两个抽象类:InputStream 、 OutputStream。
其对应子类有FileInputStream和FileOutputStream实现文件读写,
BufferedInputStream和BufferedOutputStream提供缓冲区功能。
字符流
字符流的写入write()
,读取read()
,复制copy()
,提高效率的复制fastCopy()
。
package com.changj.javaio;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
/**
* 字符流
* 字符流有两个抽象类:Writer Reader
* 其对应子类FileWriter和FileReader可实现文件的读写操作
* BufferedWriter和BufferedReader能够提供缓冲区功能,用以提高效率
*/
public static void main(String[] args) {
String path = "/Users/admin/Desktop/json/test.txt";
File f = new File(path);
if(!f.exists()){
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//写文件
//write(path);
//读文件
//read(path);
//复制文件
//copy(path);
fastCopy(path);
}
/**
* 向path文件中写入数据
* @param path
*/
private static void write(String path){
FileWriter fw = null;
try {
//以path为路径创建一个新的FileWriter对象
//如果需要追加数据,而不是覆盖,则使用FileWriter(path,true)构造方法
fw = new FileWriter(path);
//将字符串写入到流中,\r\n表示换行
fw.write("曲径通幽处,禅房花木深。\r\n");
//如果想马上看到写入效果,则需要调用w.flush()方法
fw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
//如果前面发生异常,那么是无法产生w对象的
//因此要做出判断,以免发生空指针异常
if(fw != null){
//关闭流资源,需要再次捕捉异常
try {
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 读取path文件的内容
* @param path
*/
private static void read(String path){
FileReader fr = null;
try {
fr = new FileReader(path);
//方式一
//单字符读取
// int tem = fr.read();
// System.out.println((char)tem);
//方式二
//循环读取
//单个字符读取,当temp不等于-1的时候打印字符
// int tem = 0;
// while((tem = fr.read()) != -1){
// System.out.print((char)tem);
// }
//方式三
//读入到字符数组的优化(推荐使用)
//由于有时候文件太大,无法确定需要定义的数组大小
//因此一般定义数组长度为1024,采用循环的方式读入
char[] buf = new char[1024];
int tem = 0;
while((tem = fr.read(buf)) != -1){
String s = new String(buf,0,tem);
System.out.print(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 复制
* @param path
*/
private static void copy(String path){
String copyPath = "/Users/admin/Desktop/json/copyTest.txt";
FileReader r = null;
FileWriter w = null;
try {
r = new FileReader(path);
w = new FileWriter(copyPath);
//方式一:单个字符写入
// int temp = 0;
// while((temp = r.read()) != -1) {
// w.write(temp);
// }
//方式二:字符数组方式写入
char[] buf = new char[1024];
int tem;
while((tem = r.read(buf)) != -1){
w.write(new String(buf,0,tem));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(r != null){
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(w != null){
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 利用字符流的缓冲区来进行文本文件的复制(提高效率)
*
* @param path
*/
private static void fastCopy(String path){
String copyPath = "/Users/admin/Desktop/json/copyTest.txt";
FileReader r = null;
FileWriter w = null;
//创建缓冲区的引用
BufferedReader br = null;
BufferedWriter bw = null;
try {
r = new FileReader(path);
w = new FileWriter(copyPath);
//创建缓冲区对象
//将需要提高效率的FileReader和FileWriter对象放入其构造函数内
//当然,也可以使用匿名对象的方式 br = new BufferedReader(new FileReader(path));
br = new BufferedReader(r);
bw = new BufferedWriter(w);
String line = null;
//读取行,直到返回null
//readLine()方法只返回换行符之前的数据
while((line = br.readLine()) != null) {
//使用BufferWriter对象的写入方法
bw.write(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//此处不再需要捕捉FileReader和FileWriter对象的异常
//关闭缓冲区就是关闭缓冲区中的流对象
if(br != null) {
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
字节流
字节流的写入write()
,读取read()
,复制copy()
,提高效率的复制fastCopy()
。
package com.changj.javaio;
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.io.IOException;
public class InputStreamDemo {
/**
* 字节流
* 字节流也有两个抽象类:InputStream OutputStream
* 其对应子类有FileInputStream和FileOutputStream实现文件读写
* BufferedInputStream和BufferedOutputStream提供缓冲区功能
*/
public static void main(String[] args) {
String path = "/Users/admin/Desktop/json/字节流.txt";
File f = new File(path);
if(!f.exists()){
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//写数据
//write(path);
//读数据
//read(path);
//复制
//copy();
fastCopy();
}
/**
* 向path文件中写入数据
* @param path
*/
private static void write(String path){
FileOutputStream o = null;
try {
o = new FileOutputStream(path);
String str = "曲径通幽处,禅房花木深。";
byte[] buf = str.getBytes();
//也可以直接使用o.write("String".getBytes());
//因为字符串就是一个对象,能直接调用方法
o.write(buf);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(o != null){
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 读取文件
* @param path
*/
private static void read(String path){
FileInputStream i = null;
try {
i = new FileInputStream(path);
//方式一:单个字符读取
//需要注意的是,此处我用英文文本测试效果良好
//但中文就悲剧了,不过下面两个方法效果良好
// int ch = 0;
// while((ch=i.read()) != -1){
// System.out.print((char)ch);
// }
//方式二:数组循环读取(推荐使用)
byte[] buf = new byte[1024];
int temp = 0;
while((temp = i.read(buf)) != -1) {
System.out.println(new String(buf,0,temp));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(i != null){
try {
i.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 复制
*/
private static void copy(){
String path = "/Users/admin/Desktop/json/张碧晨-我可以忘记你 (Live).mp3";
File f = new File("/Users/admin/Desktop/json/copy");
f.mkdir();
String copyPath = "/Users/admin/Desktop/json/copy/张碧晨-我可以忘记你 (Live).mp3";
FileInputStream i = null;
FileOutputStream o = null;
try {
i = new FileInputStream(path);
o = new FileOutputStream(copyPath);
//循环的方式读入写出文件,从而完成复制
byte[] buf = new byte[1024];
int temp = 0;
while((temp = i.read(buf)) != -1) {
o.write(buf, 0, temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(i != null){
try {
i.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(o != null){
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 利用字节流的缓冲区进行二进制文件的复制(提高效率)
*/
private static void fastCopy(){
String path = "/Users/admin/Desktop/json/张碧晨-我可以忘记你 (Live).mp3";
File f = new File("/Users/admin/Desktop/json/copy");
f.mkdir();
String copyPath = "/Users/admin/Desktop/json/copy/张碧晨-我可以忘记你 (Live).mp3";
FileInputStream i = null;
FileOutputStream o = null;
BufferedInputStream bi = null;
BufferedOutputStream bo = null;
try {
i = new FileInputStream(path);
o = new FileOutputStream(copyPath);
bi = new BufferedInputStream(i);
bo = new BufferedOutputStream(o);
byte[] buf = new byte[1024];
int temp = 0;
while((temp = bi.read(buf)) != -1) {
bo.write(buf,0,temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(i != null){
try {
i.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(o != null){
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}