文件字节流
文件字节流分为
- FileInputStream 常用于读取文件
- FileOutputStream 常用于写入数据进入文件
下面举一个例子(字节输出流)进行展示:
public static void InputTest(String path) {
FileInputStream is = null;
BufferedInputStream bis = null;//BufferedInputStream后续会讲解到
int size;
byte [] b = new byte[30];
try {
is = new FileInputStream(path);//进行实例化处理,path代表的文件的目录
bis = new BufferedInputStream(is);//BufferedInputStream修饰字节流,加快效率
size = bis.read(b);
//read方法;形式参数第一种方式read(byte [] b)直接读取一个字节,第二种方式read()读取一个字节,第三种read(byte [] b, int off, int len)
//len代表读取的长度,off代表偏移量(起始位置),len代表读取的长度
} catch (IOException e) {
e.printStackTrace();
}
try{
//关闭的顺序是后开的先进行关闭,先打开的后关闭
if (bis != null)
bis.close();
} catch (IOException e) {
e.printStackTrace();
}try{
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(Arrays.toString(b));
}
附上read方法的源码(总共有三种read方法的源码)
//第一种
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);//这里是从0位置直接读取数组的末尾的read方法
}
//第二种
public int read() throws IOException {
return in.read();//这是只是返回一个值的read方法
}
//第三种
public int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);//这里是自定义读取多少的read方法
}
字节输入流
//字节输入流 输入数据进入文件
public static void OutputTest(String str){
//这里的参数str指的是需要输入进文本的字符串
FileOutputStream os = null;
BufferedOutputStream bos = null;
try{
os = new FileOutputStream("d:/javaFileText/exam.txt",true);
bos = new BufferedOutputStream(os);//同理进行包装,可以加快效率
} catch (FileNotFoundException e) {
e.printStackTrace();
}try{
bos.write(str.getBytes());//getBytes(),将字符串转换为对应的byte数组
bos.flush();//flush()将缓存区的数据全部清空存储到流中
/*进行的数据操作其实都是暂时保在缓存区的,调用flush方法可以将缓存区的数据存储到流中去
避免出现文件关闭之后,数据没有导入进文件中
*/
}
catch (IOException e) {
e.printStackTrace();
}try{
if (bos != null)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}try{
if (os != null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
文件字符流
字符流可以分为
- FileReader
- FileWriter
字符输出流
public static void BIStream(String path){
//path代表的文件路径
FileReader fr = null;
BufferedReader is = null;//缓存字符流,修饰包装,加快效率
try {
fr = new FileReader(path);
is = new BufferedReader(fr);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int num = 0;
String ss;
try {
while ( (ss = is.readLine() ) != null){
/*
public String readLine()的返回值是String,作用是一行一行的读取数据
*读取is流中的文件里的数据,存储在ss中,每一次输出ss(一行文本的数据)到控制台中
*num代表的是输出的行数
*/
System.out.println("num"+num+" : "+ss);
num++;
}
} catch (IOException e) {
e.printStackTrace();
}try {
if(is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}try {
if(fr != null){
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
字符输入流
//字符输入流 输入数据进入文件
public static void BOStream(String str){
FileWriter fw = null;
BufferedWriter is = null;
try{
fw = new FileWriter("d:/javaFileText/exam.txt",true);
//FileWriter的构造方法,追加一个true代表是在文件数据的基础上增加数据,而不是覆盖文本,str代表的待输入的数据
is = new BufferedWriter(fw);
} catch (IOException e) {
e.printStackTrace();
}try{
is.write(str);
is.flush();//同文件字节流
} catch (IOException e) {
e.printStackTrace();
}try{
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}try{
if (fw != null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
附上FileWriter的源码
public FileWriter(String fileName, boolean append) throws IOException {
super(new FileOutputStream(fileName, append));
}
*/
字节数组流
包括:
- ByteArrayOutputStream
- ByteArrayInputStream
//字节数组流
public static byte[] toCharByteArray(char ch){
// 将char类型转换为byte【】类型
ByteArrayOutputStream bos = new ByteArrayOutputStreamEx();//形式参数为空
DataOutputStream dos = new DataOutputStream(bos);//数据流,转换数据
byte [] b = null;
try{
dos.writeChar(ch);//写入一个字符数据
} catch (IOException e) {
e.printStackTrace();
}
b = bos.toByteArray();
//toByteArray()返回一个字节数组,这里是长度默认为2的数组,与对应的方法有关
//如果是上面使用方法writeInt,那么这里就是创建长度为4的数组
System.out.println(b.length);
try{
if(dos != null)
dos.close();
}catch (IOException a){
a.printStackTrace();
}try{
if (bos != null)
bos.close();
}catch (IOException c){
c.printStackTrace();
}
return b;
}
/*
附上readChar方法的源码
public final void writeChar(int v) throws IOException {
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(2);
}
在使用toByteArray方法之后,那么就是创建了长度为2的数组
在本章节中,需要多去看源码助于自己理解题目意思
*/
同时包括一个特别的修饰流:DataInputStream和DataOutputStream流,可以对流进行修饰。其中存在多种方法,包括readChar()、readInt()、writeChar()、w0riteInt等,还有转换为数组toByteArray()方法,但是这里需要注意,在进行数据转换的时候,例如在toByteArray()方法前面使用了writeInt()写入一个数据进入流中,那么返回得到的一个数组长度是为4的,按照所占的类型长度来决定数据的长度,int占四个字节,所以创建四个长度的数组;故当使用wiriteChar类型的时候,创建的是2个长度的数组。
还有一个对象处理流,ObjectInputStream和ObjectOutputStream,是直接对对象处理的流,可以将一个对象输入进流之中。涉及到对象流则需要引用序列化和反序列化的概念。
序列化:指的是ObjectOutputStream流将对象转换为二进制数据,进而存储在文件中。
反序列化:指的是ObjectInputStream流将二进制数据转换为对象进行读取。
而实现序列化则需要继承序列化的接口(Serializable),该接口不存在方法,只是一个空的接口;而对于常用的普通类中都已经默认继承了该接口,所以只针对于自己定义的类需要继承Serializable接口,才可以进行序列化。
参考博客link