字节流读写文本文件内容,容易乱码。
字符流适合读取文本文件内容
每次读取一个字符返回, public int read()
public static void main(String[] args) {
try (Reader fr=new FileReader("java01\\src\\main\\java\\lian02\\b.txt");){
int c;//记住每次读取的字符编号
while ((c = fr.read()) !=-1){
System.out.print((char)c); //把c强制转换成字符
}
} catch (Exception e) {
e.printStackTrace();
}
}
每次用一个字符数组读取数据
public static void main(String[] args) {
try (Reader fr=new FileReader("java01\\src\\main\\java\\lian02\\b.txt");){
char[] chars=new char[3];
int len; //记住每次读取多少个字符
while ((len = fr.read(chars)) !=-1){
//读取多少倒出多少
System.out.println(new String(chars, 0, len));
}
} catch (Exception e) {
e.printStackTrace();
}
}
字符输出流
public static void main(String[] args) {
try(Writer fw = new FileWriter("java01\\src\\main\\java\\lian02\\b.txt",true);) {
//写入一个字符
fw.write('a');
fw.write("\r\n"); //换行符
fw.write("我爱中国");
fw.write("\r\n");
fw.write(97);
//把字符串一部分长度写出来
fw.write("我爱中国人",0,2);
fw.write("\r\n");
char[] buffer={'我','爱','中','国','a'};
fw.write(buffer);
fw.write(buffer,0,3);
} catch (Exception e) {
e.printStackTrace();
}
}
字节流适合做一切文件的拷贝(音视频,文本);字节流不适合做文本输出
字符流适合做文本文件的操作(读,写)。
缓冲流(对原始流包装,以提高原始流读写数据性能)
字节缓冲流
public static void main(String[] args) {
//字节缓冲流
try( InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
InputStream bis=new BufferedInputStream(is);
OutputStream os = new FileOutputStream("java01\\src\\main\\java\\lian02\\c.txt");
OutputStream bos=new BufferedOutputStream(os);
)
{
byte[] bytes=new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1){
bos.write(bytes,0,len);
}
System.out.println("复制完成");
} catch (Exception e) {
e.printStackTrace();
}
}
字符缓冲流输入流
public static void main(String[] args) {
try( Reader fr = new FileReader("java01\\src\\main\\java\\lian02\\b.txt");
//这里不用多态封装,是因为BufferReader自带有readLine()方法。
BufferedReader br=new BufferedReader(fr);)
{
// char[] buffer=new char[3];
// int len;
// while ((len =br.read(buffer)) !=-1) {
// System.out.println(new String(buffer,0,len));
// }
//用BufferReader带有的ReadLine方法
String line; //记住每次读取的一行数据
while (( line = br.readLine()) !=null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
字符缓冲输出流
BufferWriter多了新功能换行,newLine()
public static void main(String[] args) {
try ( Writer fw = new FileWriter("java01\\src\\main\\java\\lian02\\b.txt",true);
BufferedWriter bw=new BufferedWriter(fw);)
{
bw.newLine();
bw.write('p');
bw.write('中');
bw.write("China");
char[] buffer={'我','爱','中','国'};
bw.write(buffer);
} catch (Exception e) {
e.printStackTrace();
}
}
案例-给诗排序
给诗排序,并存到另一个文件中
public static void main(String[] args) {
try (BufferedReader br=new BufferedReader(new FileReader("java01\\src\\main\\java\\lian02\\b.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("java01\\src\\main\\java\\lian02\\a.txt"));
)
{
List<String> list=new ArrayList<>();
String line; //按照行读
while ((line = br.readLine()) != null) {
list.add(line);
}
Collections.sort(list);
System.out.println(list);
for (String s : list) {
bw.write(s);
bw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
原始流和缓冲流性能分析
private static final String diZhi01 = "D:\\video\\video01.mp4";
private static final String diZhi02 = "D:\\video00\\video.mp4";
public static void main(String[] args) {
copy02();
copy03();
copy04();
}
//低级字节输出流
public static void copy01(){
long startTime = System.currentTimeMillis();
try(InputStream is=new FileInputStream(diZhi01);
OutputStream os=new FileOutputStream(diZhi02);
)
{
int b;
while ((b=is.read()) !=-1){
os.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("低级字节输出流消耗时间为"+(endTime - startTime) / 1000.0 +"s");
}
//低级字节数组输出流
public static void copy02(){
long startTime = System.currentTimeMillis();
try( InputStream is=new FileInputStream(diZhi01);
OutputStream os=new FileOutputStream(diZhi02);)
{
byte[] buffer=new byte[1024];
int len;
while ((len = is.read(buffer)) !=-1){
os.write(buffer,0,len);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("低级数组消耗时间"+(endTime-startTime) / 1000.0 +"s");
}
//使用高级缓冲字节
public static void copy03(){
long startTime = System.currentTimeMillis();
try ( BufferedReader br = new BufferedReader(new FileReader(diZhi01));
BufferedWriter bw= new BufferedWriter(new FileWriter(diZhi02));)
{
int b;
while ((b = br.read()) !=-1){
bw.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("高级字节缓冲流消耗时间" + (endTime - startTime) / 1000.0 +"s");
}
//高级缓冲字节数组流
public static void copy04(){
long startTime = System.currentTimeMillis();
try( Reader is=new FileReader(diZhi01);
BufferedReader br=new BufferedReader(is);
Writer os=new FileWriter(diZhi02);
BufferedWriter bw=new BufferedWriter(os);
)
{
char[] buffer=new char[1024];
int len;
while ((len = br.read(buffer)) !=-1){
bw.write(buffer,0,len);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("高级缓冲数组消耗时间"+(endTime-startTime) / 1000.0 +"s");
}
字符输入转换流(重要)
把GBK文件读取出来
public static void main(String[] args) {
try(
//1.得到文件的原始字节流
InputStream is=new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
//2.把原始的字节输入流按着指定的字符集编码转换成字符输入流
Reader isr=new InputStreamReader(is,"GBK");
//3.把字符输入流包装成缓冲字符输入流
BufferedReader br=new BufferedReader(isr);)
{
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
字符输出转换流
需要控制写出去的字符使用什么字符集编码,该怎么办?
1.调用String的getBytes方法解决
String data = "我爱你中国";
byte[] bytes=data.getBytes("GBK");
2.字符输出转换流
public static void main(String[] args) throws UnsupportedEncodingException {
try ( //1.得到原始的字节输出流
OutputStream os=new FileOutputStream("java01\\src\\main\\java\\lian02\\b.txt");
//2.将原始的字节输出流,按着指定编码转换成字符输出流
Writer writer = new OutputStreamWriter(os, "GBK");
//3.将字符输出流封装为缓冲字符输出流
BufferedWriter bw= new BufferedWriter(writer);)
{
bw.write("我");
bw.write("爱");
bw.write("你");
} catch (Exception e) {
e.printStackTrace();
}
}
打印流
public static void main(String[] args) throws UnsupportedEncodingException {
try (
PrintStream ps = new PrintStream("java01\\src\\main\\java\\lian02\\b.txt", Charset.forName("GBK"));
)
{
ps.println("wo");
ps.println("江南江北一条街");
} catch (Exception e) {
e.printStackTrace();
}
}
PrintStream和PrintWriter用法基本上差不多,打印数据没有区别,写数据上有区别。
高级流后面不能直接写追加,高级流封装低级流,在低级流中写追加。
数据流
IO-序列化流
对象序列化:把Java对象写入到文件当中去
对象反序列化:把文件里的Java对象读取出来
对象如果需要序列化,必须实现序列化接口
首先创建对象类,必须实现Serializable接口
public class User implements Serializable {
private String loginName;
private String userName;
private int age;
private String passWord;
public User() {
}
public User(String loginName, String userName, int age, String passWord) {
this.loginName = loginName;
this.userName = userName;
this.age = age;
this.passWord = passWord;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public String toString() {
return "User{" +
"loginName='" + loginName + '\'' +
", userName='" + userName + '\'' +
", age=" + age +
", passWord='" + passWord + '\'' +
'}';
}
}
序列化对象三步走
public class Test05 {
public static void main(String[] args) {
try (
//2.创建对象字节输出流包装原始的对象字节输出流
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("java01\\src\\main\\java\\lian02\\b.txt"));)
{
//1.创建一个java对象
User user=new User("admin","张三",23,"666777xx");
//3.序列化对象到文件中去
os.writeObject(user);
System.out.println("序列化对象成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
对象字节输入流
public class Test05 {
public static void main(String[] args) {
try {
//1.建立对象序列化输入流管道,封装原始字节输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt"));
User user = (User) ois.readObject();
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
成员变量中,加上transient修饰符,将不参与序列化
先用ArrayList<User> 集合封装对象
public static void main(String[] args) {
try( ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("java01\\src\\main\\java\\lian02\\a.txt"));)
{
User user1=new User("admin","张三",23,"666777xx");
User user02=new User("admin2","李四",20,"98980xx");
User user03=new User("admin3","王五",24,"909000ll");
ArrayList<User> list=new ArrayList<>();
list.add(user1);
list.add(user02);
list.add(user03);
oos.writeObject(list);
System.out.println("序列化成功");
} catch (Exception e) {
e.printStackTrace();
}
}
将ois.readObject()强制转换成ArrayList<User> 类型
public static void main(String[] args) {
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("java01\\src\\main\\java\\lian02\\a.txt"));)
{
ArrayList<User> o = (ArrayList<User>) ois.readObject();
for (User user : o) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
}
}
IO-流框架
静态方法,直接调用
FileUtils.copyFile();