十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
存储和读取数据的解决方案
作用主要是两点:保存数据(写 output) 和 读取数据(读 input)
1.1、IO流的分类1.2、小结存储和读取数据的解决方案 I:input O:output 流:像水一样传输数据
用于读写数据(本地文件,网络文件)
输出流:程序 到 文件
输入流:文件 到 程序
字节流:可以操作所有类型文件
字符流:只能操作纯文本文件
用记事本打开能看懂的文件
FileOutputStream :File 作用 OutputStream 继承
功能:操作本地文件的字节流输出
书写步骤:
1.路径可以是字符串也可以是File对象
2.文件不存在会自动创建一个文件,但是父级路径必须存在
3.文件已经存在,则会自动清空原文件内容,再书写
write方法的参数是整数,会找对应的ASCII上的内容
IO流操作中都要进行的操作
一次写一个字节数据
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {// 创建对象
FileOutputStream file = new FileOutputStream("oj\\a.txt");
// 写数据
file.write(97);
// 释放资源
file.close();
}
}
一次写一个字节数组
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {byte[] b = {97,98,99};
FileOutputStream file = new FileOutputStream("oj\\a.txt");
file.write(b);
file.close();
}
}
一次写一个字节数组的一部分
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {byte[] b = {97,98,99};
FileOutputStream file = new FileOutputStream("oj\\a.txt");
file.write(b,0,2);//write(b,0,2):write(数组,开始索引,数据长度len)
file.close();
}
}
换行:
书写的时候 加上 file.write(“\r\n”);(换行符)
续写:创建对象的时候打开 续写开关
FileOutputStream file = new FileOutputStream(“oj\a.txt”,true);
FileInputStream:File 作用 InputStream 继承
功能:读取本地文件的数据到程序
书写步骤:
创建字节流输入对象文件不存在,直接报错
读数据一次读一个,读到末尾为-1,
释放资源IO流操作中都要进行的操作
读取一个字节数据
// a.txt 内 为ab
import java.io.FileInputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {FileInputStream file = new FileInputStream("a.txt");
int a = file.read();
System.out.println((char) a);//结果:a
int a2 = file.read();
System.out.println((char)a2);//结果:b
int a3 = file.read();
System.out.println(a3);//没有这个数据结果:-1
file.close();
}
}
一次读取一个字节数组
//a.txt内为asd
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {FileInputStream file = new FileInputStream("a.txt");
byte[] b = new byte[2];
int len = file.read(b);
System.out.println(len);
//转换成字符串
//如果不做限定直接写new String(b)输入的数据会不对,可以试一试
String str = new String(b,0,len);
System.out.println(str);
int len2 = file.read(b);
System.out.println(len2);
String str2 = new String(b,0,len2);
System.out.println(str2);
file.close();
}
}
循环读取
import java.io.FileInputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {FileInputStream file = new FileInputStream("a.txt");
int b;
while ((b=file.read()) != -1){System.out.print((char)b);
}
file.close();
}
}
2.1.3、文件拷贝文件拷贝基本代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {FileInputStream file = new FileInputStream("E:\\oo\\b.txt");
FileOutputStream outFile = new FileOutputStream("a.txt");
int b ;
while ((b = file.read()) != -1){outFile.write(b);
}
//规则:先开的后关闭
outFile.close();
file.close();
}
}
2.1.3.1、文件拷贝的弊端和解决方案基本代码是一个一个读取,速度很慢
所以要用数组的方式 来循环,一次获得多个字节数据
改写后
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {FileInputStream file = new FileInputStream("E:\\oo\\b.txt");
FileOutputStream outFile = new FileOutputStream("a.txt");
byte[] b = new byte[1024*1024*5];// 数组长度 一般是1024的整数倍
int len ;
while ((len = file.read(b))!= -1){outFile.write(b,0,len);
}
outFile.close();
file.close();
}
}
2.2、字符流底层就是字节流
特点:
输入流:一次读一个字节,遇到中文读取多个字节
输出流:底层会按照指定的编码方式编码,变成字节再写入文件中
使用场景:适合用于纯文本文件的操作
FileReader:名字命名方式和字节流一样
书写格式:与字节流一样
一次读一个数据
import java.io.FileReader;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {FileReader file = new FileReader("a.txt");
int read;
while ((read = file.read()) != -1){//强化成字符
System.out.print((char)read);
}
file.close();
}
}
一次读多个数据
import java.io.FileReader;
import java.io.IOException;
public class Main {public static void main(String[] args) throws IOException {FileReader file = new FileReader("a.txt");
char[] ca = new char[2];
int len;
while ((len = file.read(ca))!= -1) {String st = new String(ca,0,len);
System.out.print(st);
}
file.close();
}
}
2.2.2、字符输出流与字节输出一致
三、其他流 3.1、缓冲流3.1.1、字节缓冲流一次读取一个字节
package org.example;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException {// 要传入基本的FileInputStream和FileOutputStream类型 底层会创建一个byte[8192]的数组 作为缓冲区
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("v.txt"));
int b;
while (( b = bis.read())!=-1){bos.write(b);
}
// 直接关闭缓冲流,因为底层会关闭基本的字节流
bos.close();
bis.close();
}
}
一次读取多个字节
package org.example;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("v.txt"));
byte[] bytes = new byte[10];
int len;
while (( len = bis.read(bytes))!=-1){bos.write(bytes,0,len);
}
bos.close();
bis.close();
}
}
3.1.1.1、字节缓冲流原理3.1.2、字符缓冲流真正输入输出的还是基本流
缓冲流会在内存当中创建一个长度8192的字节数组,输入和输出各创建一个,
缓冲流会一次性读8192的字节,和写8192字节
read()和write() 只是在内存中不停的将 数据字节从输入缓冲流挪到输出缓冲流
数据在内存中是非常快的,节约的是读和写的时候和硬盘打交道的时间
跟字节缓冲流差不多,但有两个重要的特有方法readLine()和newLine()
readLine() 一次读一行,碰到换行结束
package org.example;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String a = br.readLine();
System.out.println(a);
br.close();
}
}
newLine() 跨平台的换行,每个操作系统换行符不一样
package org.example;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException {BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
bw.write("123");
bw.newLine();
bw.write("abc");
bw.close();
}
}
3.2、序列化流(对象操作输出流)和反序列化流(对象操作输出流)将java对象写到本地文件 和 读取到本地文件
ObjectOutputStream()
和ObjectInputStream()
序列化流
writeObject()写入输出对象
细节:被输出的javaBean类要去 实现 Serializable,不然会报错
因为一旦实现了这个接口,就代表本类可以被序列化,可以理解成打上了合格证
public class student implements Serializable
package org.example;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException {student stu = new student("张三", 12);
// 输出位置
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("a.txt"));
//写入输出的对象
os.writeObject(stu);
os.close();
}
}
反序列化流
readObject()读取对象信息
package org.example;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException, ClassNotFoundException {// 需要读取的位置
ObjectInputStream ojs = new ObjectInputStream(new FileInputStream("a.txt"));
//读取数据
Object o = ojs.readObject();
//打印数据
System.out.println(o);//结果;student{name = 张三, age = 12}
ojs.close();
}
}
3.2.1、细节汇总1.使用序列化时,要给被序列化的JavaBean类 实现 Serializable 接口 ,相当于打上一个合格证,允许被序列化
2.被序列化的文件不能修改,修改了就读不出了
3. 序列化后,修改了JavaBean类,再次反序列化,会不会出现问题?会抛出异常
解决方案:给JavaBean类 添加变量serialVersionUID(类似于版本号)
可以直接写,名字是固定的(不推荐)
用IDEA 生成(推荐)
转换流是字符流下的,是字节流和字符流的桥梁,可以用于不同编码方式的转换
package org.example;
import java.io.*;
import java.nio.charset.Charset;
public class Main {public static void main(String[] args) throws IOException {// JDK 11 以前用 InputStreamReader() 和 OutputStreamWriter()
FileReader fr = new FileReader("b.txt", Charset.forName("GBK"));
FileWriter fw = new FileWriter("a.txt", Charset.forName("UTF-8"));//IDEA 默认是UTF-8 可以不写
int len;
while ((len = fr.read())!=-1){fw.write(len);
}
fw.close();
fr.close();
}
}
3.4、打印流PrintWriter() 和 PrintStream()
3.4.1、字节打印流你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧