上次我们提到了一个随机读写类RandomAccessFile,可以实现对文件内容的操作,但是却过于复杂,所以一般情况下操作文件内容都使用字节流和字符流。
在程序中所有的数据都是以流的的方式进行传输或者保存。读取数据用输入流,保存数据用输出流。
字节流和字符流都有对文件的读写操作,字节流中读用InputStream,写用OutputStream。字符流中读用Reader类,写用Writer类。
进行IO操作也是有步骤的,主要流程如下:
(1)使用File类打开一个文件
(2)通过字节流或者字符流的指定输出位置
(3)进行读写操作
(4)关闭流
一.字节流
OutputSteam是整个IO包内输出流最大的父类,而且它是一个抽象类。使用此类,必须通过子类实例化对象。如向文件写入字符串,代码如下:
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class OutputStreamDemo {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test2.txt");
OutputStream ops=new FileOutputStream(f);
String str="Java io test";
byte[] b=str.getBytes();
ops.write(b);
ops.close();
}
}
上面是把字符串变成一个byte数组,然后把数组写进文件,也可以把用for循环一个字节一个的写进文件,代码如下:import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class OutputStreamDemo2 {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test3.txt");
OutputStream ops=new FileOutputStream(f);
String str="java io test";
byte[] b=str.getBytes();
for(int i=0;i<b.length;i++) {
ops.write(b[i]);
}
ops.close();
}
}
如果我们重新执行程序,就会覆盖文章原来的内容,那我们怎么解决这样的问题,我们只要修改下面这段代码
OutputStream ops=new FileOutputStream(f,true);
这样的话,再执行程序的话,新加入的内容就会添加到原来的内容后面,但是又有问题了,如果我们不想接在原来的内容后面,而是换行输入呢?哈哈,我们只需要在上面代码定义的字符串前加“\r\n”
String str="\r\njava io test";
(2)InputStream
这个类是读文件的,怎么实现和OutputStream一样。直接上代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test3.txt");
InputStream ips=new FileInputStream(f);
byte[] b=new byte[1024];
int len=ips.read(b);
ips.close();
System.out.println("文件数据长度:"+len);
System.out.println("文件内容是:");
System.out.println(new String(b,0,len));
}
}
如果读取的路径不存在,程序运行的时候回出现异常。上面的代码虽然能够读出文件内容,但是由于是通过byte数组接受内容,如果字符很小的话,会造成空间浪费。如果能根据文件大小创建数组就更好了!刚好File类中存在一个length()方法,这个方法能得到文件大小。代码如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo2 {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test2.txt");
InputStream ips=new FileInputStream(f);
byte[] b=new byte[(int)f.length()];
int len=ips.read(b);
ips.close();
System.out.println("内容为:"+new String(b,0,len));
}
}
也可以通过for循环从文件中一个个的读出来,直接使用read()方法读。
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo3 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test2.txt");
InputStream ips=new FileInputStream(f);
byte[] b=new byte[(int)f.length()];
for(int i=0;i<b.length;i++) {
b[i]=(byte) ips.read();
}
ips.close();
System.out.println("内容是:"+new String(b));
}
}
但是呢,这些都是知道具体数组大小的前提下实现的,那我们要是不知道数组大小呢,则只能通过判断是否读到文件末尾的方式来读取数据,文件独大最后返回-1,具体代码如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo4 {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test2.txt");
InputStream ips=new FileInputStream(f);
int temp=0;
byte[] b=new byte[1024];
int len=0;
while((temp=ips.read())!=-1) {
b[len]=(byte)temp;
len++;
}
ips.close();
System.out.println("内容为:"+new String(b,0,len));
}
}
二.字符流
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class WriterDemo {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test2.txt");
Writer wt=new FileWriter(f);
String str="java io Writer test";
wt.write(str);
wt.close();
}
}
整个程序和OutputStream写入文件基本上没什么差别,就是使用Writer类不需要把字符串变成byte数组,而是直接输出字符串。Writer wt=new FileWriter(f);
修改成Writer wt=new FileWriter(f,true);
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class ReaderDemo2 {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test2.txt");
Reader rd=new FileReader(f);
char[] c=new char[1024];
int len=rd.read(c);
rd.close();
System.out.println("内容为:"+new String(c,0,len));
}
}
如果不知道文件大小,也可以像上面的那样用循环的方式进行读取,代码如下:import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class RederDemo {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
File f=new File("d:"+File.separator+"test2.txt");
Reader rd=new FileReader(f);
int len=0;
int temp=0;
char[] c=new char[1024];
while((temp=rd.read())!=-1) {
c[len]=(char) temp;
len++;
}
rd.close();
System.out.println("内容为:"+new String(c,0,len));
}
}