了解I/O流
首先简单了解一下java的I/O流,流就相当于一个管道,数据从一个地方传送到另一个地方需要建立一个数据通路,这个通路称做流。对应的就有输入流和输出流,注意这里的输入输出是相对内存而言的。读取文件内容是将文件内容放入内存,对应的是输入流;将数据写入文件是把内存中的数据放入文件,对应的是输出流。java的整个I/O体系内容很多,这里我们只讲文件相关的流。
文件读取
1、创建文件对象。
File类是一个文件类,可以用File类创建一个文件对象,对象包含了文件属性的相关方法,如设置文件属性、读取文件修改时间、文件大小等。
2、为文件对象建立字节输入流。
FileInputStream类是个文件字节输入流类,初始化的时候要指定为哪个文件对象创建字节流。
3、读取数据。由于是字节流,所以需要循环读取每一个有效字节数
4、关闭输出流
import java.io.*;
public class TestFile{
public static void main(String[] args){
File fname=new File("d:\\abc.txt");//创建文件对象,指向abc.txt这个文件
try{
InputStream f=new FileInputStream(fname);//为fname文件对象创建字节流
int size=f.available();
for(int i=0;i<size;i++)
System.out.print( (char) f.read() );//强制类型
f.close();
}
catch(IOException e){
System.out.println("文件读取失败");
}
}
}
文件写入
基本操作是类似的,创建文件对象、建立字节流、写入、关闭流。文件写入就将输入流改为输出流。写的时候要注意,字节流要按字节的方式读写,因此写入的内容也要是字节形式的,将要写入的内容放进一个字节数组里。
import java.io.*;
public class TestFile{
public static void main(String[] args){
File fname=new File("d:\\abc.txt");
String str="好好学习!";
byte[] words=str.getBytes();//将字符串以字节形式放入字节数组
try{
OutputStream fout=new FileOutputStream(fname,true);//true代表append为真,即往文件中追加内容,如果不写true则会覆盖原内容
fout.write(words);//将字节数组words的内容写入
System.out.println("文件追加成功!");
fout.close();
}
catch(IOException e){
System.out.println("文件失败!");
}
}
}
更好的办法。写入文件要把字符串转为字节数组,有没有更好的办法可以直接写入呢?当然是有的,java为我们提供了字符流,使用字符流就可以不用将字符串转为字节数组这么麻烦。字符流实际上是对字节流的包装,使用字符流需要指定要包装的字节流。OutputStreamWriter和InputStreamReader分别是写字符流和读字符流,它们分别继承于Writer和Reader抽象类。使用字符流就可以只用一行将内容写入文件。
import java.io.*;
public class testFile{
public static void main(String[] args){
try{
File fname=new File("d:\\abc.txt");
FileOutputStream fos=new FileOutputStream(fname);//指定文件对象fname
OutputStreamWriter osw=new OutputStreamWriter(fos);//指定字节流fos
osw.write(“好好学习\n”);//写文件
osw.close();
}
catch(IOException e){
System.out.println("error");
}
}
}
更更好的方法。有没发现写入数据需要建立文件对象、字节流、字符流,这里有更方便的方法将这三步一起做了。就是使用FileWriter和FileReader这两个类,它们直接继承了OutputStreamWriter和InputStreamReader。
import java.io.*;
public class TestFile{
public static void main(String[] args){
try{
FileWriter fw = new FileWriter("d:\\abc.txt",true);
fw.write("\r\n好好学习");// \r\n是回车换行,新起一行写入
fw.close();
}
catch(IOException e){
e.printStackTrace();
}
}
}
这样文件写入就变得十分简单易懂,不用管太多流的包装,当然前期理论很重要,都是先难后易的嘛。
文件复制
文件复制其实就是先将文件内容一行一行读出来,每读取一行就把读到的内容放到新的文件里去,然后一直读直到读完为之。这里为了更好的操作使用了缓冲流BufferedWriter和BufferedReader,缓冲流是对字符流的包装,不用缓冲流其实也行,但是用缓冲流会高效一点。使用缓冲流要注意的是,读取到的内容是放在缓冲区,最后要使用flush将缓冲区内容冲走。
import java.io.*;
public class TestFile{
public static void main(String[] args){
try{
FileWriter fw=new FileWriter("d:\\abc_copy.txt",true);
BufferedWriter bw=new BufferedWriter(fw);
FileReader fr=new FileReader("d:\\abc.txt");
BufferedReader br=new BufferedReader(fr);
String line;
while((line=br.readLine())!=null) {
System.out.println(line);
bw.write(line);
bw.flush();
bw.newLine();
}
br.close();
bw.close();
}
catch(IOException e){
e.printStackTrace();
}
}
}
最后附上代码中的流的关系图: