如果要进行输入输出操作一般都会按照如下的步骤进行:
---通过File类定义了一个要操作文件的路径;
---通过字节流或字符流的子类对象为父类对象实例化;
---进行数据的读(输入),写(输出)操作;
---数据量属于资源操作,资源操作必须关闭;
对于java.io包而言它定义了两类流:
---字节流(JDK1.0):InputStream,OutputStream;
---字符流(JDK1.1)Reader,Writer
字节输出流:OutputStream
该类的定义:public abstract class OutputStream
extends Object
implements Closeable, Flushable
首先发现该类实现了两个接口:Closeable, Flushable。这两个接口定义如下:
Closeable接口(JDK1.5):public interface Closeable //在JDK1.7之后引入了非常神奇的自动关闭机制,所以让Closeable多继承了一个AutoCloseable
public interface Closeable extends AutoCloseable{
public void close() throws IOException;
}
Flushable接口(JDK1.5):void flush() throws IOException
在OutputStream类里面一共提供有三个输出的方法:
---输出单个字节:public abstract void write(int b) throws IOException
---输出全部字节数组:public void write(byte[] b) throws IOException
---输出部分字节数组:public void write(byte[] b, int off, int len) throws IOException
OutputStream本身属于抽象类,如果想要为抽象类进行对象的实例化操作,那么一定要使用子类进行操作,于是进行的是文件操作所可以使用FileOutpuStream子类。在这个子类里定义有如下的构造方法:
---创建或覆盖已有文件:public FileOutputStream(File file)throws FileNotFoundException
---文件内容追加:public FileOutputStream(File file,boolean append)throws FileNotFoundException
范例:文件内容的输出:
package test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Demo01 {
public static void main(String[] args) throws Exception {//此处直接抛出
File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输出的文件路径
//此时由于目录不存在,所以文件不能输出,那么应该首先创建目录
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();//创建目录
}
//应该使用OutputStream和其子类进行对象的实例化,此时目录存在,文件还不存在
OutputStream outputStream=new FileOutputStream(file);
//要进行文件内容的输出
String string="好好学习,天天向上";
byte data[]=string.getBytes();//将字符串变为字节数组
outputStream.write(data); //将内容输出
outputStream.close();//资源操作的最后一定要关闭
}
}
以上是将整个字节数组的内容进行输出,并且发现,如果此时要输出的文件不存在,那么会自动进行创建。可是对于输出操作在整个OutputStream类里面一共定义有三个操作方法。
范例1:采用单个字节的方式输出。
for(int x=0;x<data.length;x++){
output.write(data[x]);
}
范例2:输出部分字节数组内容
output.write(data,6,6);
但是每次都是覆盖不是很好,希望可以实现内容的追加,那么只需要更换FileOutputStream类的构造方法即可。
//应该使用OutputStream和其子类进行对象的实例化,此时目录存在,文件还不存在
OutputStream outputStream=new FileOutputStream(file,true);
//要进行文件内容的输出
String string="好好学习,天天向上 \r\n";
字节输入流:InputStream
如果程序需要进行数据的读取操作,可以利用InputStream类实现功能,此类定义如下:
public abstract class InputStream extends Object implements Closeable
虽然也定义了Closeable接口,但是与OutputStream类一样,不用去考虑此接口的存在。在InputStream里面也定义有数据读取的方法。
---读取单个字节:public abstract int read() throws IOException
---将读取到的数据保存在字节数组里面:public int read(byte[] b)throws IOException
---将读取到的数据保存在部分字节数组里:public int read(byte[] b,int off,int len)throws IOException
InputStream类是抽象类,因此如果想要为抽象类进行实例化操作,那就使用其子类FileInputStream类进行实例化操作。该子类的构造方法:
public FileInputStream(String name) throws FileNotFoundException
范例:向数组里读取数据
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Demo01 {
public static void main(String[] args) throws Exception {//此处直接抛出
File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
//需要判断文件存在后才可以进行读取
if (file.exists()) {
//使用InputStream类进行读取
InputStream inputStream=new FileInputStream(file);
byte data[]=new byte[1024];//准备输出一个1024的数组
int len=inputStream.read(data);//将字节内容保存到字节数组之中
inputStream.close();
System.out.println("["+new String(data,0,len)+"]");
}
}
}
范例:单个字节数据读取
---由于一个文件存在很多的字节数据,所以如果要读取肯定采用循环的方式进行读取,由于不确定循环次数,所以使用while()循环完成。
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Demo01 {
public static void main(String[] args) throws Exception {//此处直接抛出
File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
//需要判断文件存在后才可以进行读取
if (file.exists()) {
//使用InputStream类进行读取
InputStream inputStream=new FileInputStream(file);
byte data[]=new byte[1024];//准备输出一个1024的数组
int foot=0;//表示字节数组的操作指标
int temp=0;//表示每次读取的字节数据
while ((temp=inputStream.read())!=-1) {//将read()方法读取的字节内容给了temp变量,并且判断读取的内容是否为-1
data[foot++]=(byte)temp;
}
inputStream.close();
System.out.println("["+new String(data,0,foot)+"]");
}
}
}
字符输出流:Writer
writer类是在JDK1.1之后增加的,其类的定义如下:
public abstract class Writer extends Object implements Appendable, Closeable, Flushable
这个类除了实现 Closeable, Flushable接口外,又多实现了一个接口Appendable,这个接口定义如下:
public interface Appendable
public interface Appendable{
Appendable append(char c)
// 向此 Appendable 添加指定字符。
Appendable append(CharSequence csq)
// 向此 Appendable 添加指定的字符序列。
Appendable append(CharSequence csq, int start, int end)
// 向此 Appendable 添加指定字符序列的子序列。
}
在Appendable中定义了追加的操作,而且追加的数据都是字符或者字符串。
在Writer类里面定义有以下的输出方法(部分):
---输出全部字符数组:public void write(char[] cbuf) throws IOException
---输出字符串:public void write(String str) throws IOException
Writer是一个抽象类,如果想要为这个类的对象实例化,应该使用FileWriter子类。
范例:使用Writer类进行内容输出
package test;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class Demo01 {
public static void main(String[] args) throws Exception {//此处直接抛出
File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
//需要判断文件存在后才可以进行读取
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
//实例化Writer类的对象
Writer out=new FileWriter(file);
//进行内容输出
String string="千万不要被节后综合征所打败";
out.write(string);//输出字符串数据
out.close();//关闭输出流
}
}
可以发现Writer作为字符输出流,可以直接进行字符串的输出,这一点就比OutputStream强了
字符输入流:Reader
Reader是进行字符数据读取的输入流,其本身也是一个抽象类:
public abstract class Reader extends Object implements Readable, Closeable
在Reader类里面也提供有一系列的read()方法:
---读取内容到字符数组:public int read(char[] cbuf) throws IOException
返回值:表示读取的数据长度,如果以及读取到结尾了返回-1.
为Reader类实例化的可以使用FileReader子类完成。
范例:使用Reader
package test;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class Demo01 {
public static void main(String[] args) throws Exception {//此处直接抛出
File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
//需要判断文件存在后才可以进行读取
if (file.exists()) {
//为Reader类对象实例化
Reader in=new FileReader(file);
//进行数据读取
char data []=new char [1024];
int len=in.read(data);
//关闭输入流
in.close();
System.out.println(new String(data,0,len));
}
}
}
与字节输入流相比结构几乎是一样的,只是数据类型由byte改为char而已。
字节流和字符流的区别?
字节流和字符流最大的区别是,字节流直接与终端进行交互,而字符流需要将数据经过缓冲区处理后才可以输出。
在使用OutputStream输出数据的时候即使最后没有没有关闭输出,那么内容也可以正常输出。但如果使用的的是字符输出流,如果不关闭,那么就表示在缓冲区之中处理的内容不会被强制性地清空,所以就不会输出数据。如果某种情况下不能关闭字符输出流,可以使用flush方法强制清空缓冲区。
范例:强制清空字符流缓冲区。out.flush();
在开发之中,对于字节数据地处理是比较多的,例如:图片,音乐,电影。。。。。对于字符流最大的好处是它可以进行中文地有效处理。在以后地开发之中,如果要处理中文的时候请优先考虑字符流,如果没有中文问题,建议使用字节流。
2018-08-12 20.54