IO流
IO流
-
File 文件操作
-
IO流
IO: input和output
System.in
System.out
文件流
处理流:
带有缓冲区的流
转换流
对象流
File类
File类:表示一个文件或者文件夹
import java.io.File;
public class Test {
public static void main(String[] args) {
try {
// File file = new File("abc/def/吼吼吼.txt");
// file.createNewFile(); // 创建一个文件,不包含文件夹
// System.out.println(file.getParentFile()); // 拿到上一层文件夹的对象
// System.out.println(file.getParent()); // 拿到文件名
//
// file.mkdir(); // 创建文件夹,只能创建一个
// file.mkdirs(); // 创建多级文件夹一定选这个,可以帮我们把上级目录创建出来
// file.renameTo(new File("abv/def/吼吼吼.txt")); // 重命名
// file.delete(); // 删除文件
// 查看相关
// System.out.println(file.exists()); // 查看文件是否存在
// System.out.println(file.isAbsolute()); // 判断是否绝对路径
// System.out.println(file.isDirectory()); // 查看文件是否是文件夹
// System.out.println(file.isFile()); // 判断文件是否是文件
// System.out.println(file.length()); // 查看文件大小
// System.out.println(file.getName()); // 查看文件名
// 创建文件完整步骤
File file = new File("abc/def/吃饭.txt");
// 1.先判断上层文件夹是否存在
File parentFile = file.getParentFile();
if (!parentFile.exists()){
parentFile.mkdirs(); // 创建多级文件夹
}
// 2.创建文件
file.createNewFile();
} catch (Exception e){
e.printStackTrace();
}
}
}
运行结果:
IO流-节点流
流的分类:
-
按照读写的方向来讲,分类输入流和输入出流,站在程序的角度去分析
-
按照读写内容的单位来讲,分为字节流和字符流
-
按照流的功能不同,分为节点流和处理流
节点流:直接连接在文件上的
处理流:套在其他流上的
输入 | 输出 | |
---|---|---|
字节流 | InputStream | OutputStream |
字符流 | Reader | Writer |
文件流
FileInputStream:文件字节输入流
import java.io.File;
import java.io.FileInputStream;
public class TestFileInputStream {
public static void main(String[] args) throws Exception{
// 创建流
FileInputStream fis = new FileInputStream(new File("a.txt"));
// int b = fis.read();
// System.out.println((char)b); // 读取
// int b1 = fis.read();
// System.out.println((char)b1);
// byte[] bs = new byte[1024];
// int len = fis.read(bs); // 返回读取了多少个字节
// System.out.println(new String(bs,0,len));
// 读取文件最重要的一套写法
byte[] bytes = new byte[1024]; // 读取1024字节
int len = 0;
// 只限在读文件这么写判断
while((len=fis.read(bytes))!=-1) {
String s = new String(bytes,0,len);
System.out.println(s);
}
fis.close();
}
}
运行结果:
FileOutputStream:文件字节输出流
import java.io.File;
import java.io.FileOutputStream;
public class TestFileOutputStream {
public static void main(String[] args) throws Exception{
// 加上true 不清空原数据
FileOutputStream fos = new FileOutputStream(new File("a.txt"),true);
fos.write("谁都很帅".getBytes());
// 好习惯
fos.flush(); // 刷新
fos.close(); // 关闭
}
}
运行结果:
FileReader:文件字符输入流
import java.io.File;
import java.io.FileReader;
public class TestFileReader {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader(new File("a.txt"));
// int i = fr.read(); // 以字符为单位
// System.out.println((char)i);
// char[] cs = new char[1024];
// int len = fr.read(cs);
// System.out.println(new String(cs,0,len));
char[] cs = new char[1024];
int len = 0;
while ((len= fr.read(cs))!=-1){
System.out.println(new String(cs,0,len));
}
// 读取不用刷新
fr.close();
}
}
运行结果:
FileWriter:文件字符输出流
import java.io.File;
import java.io.FileWriter;
public class TestFileWrite {
public static void main(String[] args) throws Exception{
FileWriter fw = new FileWriter(new File("a.txt"),true);
// fw.write("\r\n"); 换行
fw.write("我能写字符串了,哎哟,不错哦");
fw.flush();
fw.close();
}
}
运行结果:
如何选择流:
字符流:读取文件中的文字信息
字节流:读取非文本文件的时候
练习:剪切图片从d盘到f盘
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test {
public static void main(String[] args) throws Exception{
File f = new File("D:/hsq.jpg");
FileInputStream fis = new FileInputStream(f);
FileOutputStream fos = new FileOutputStream(new File("F:/hsq.jpg"));
byte[] bs = new byte[1024];
int len = 0;
while ((len=fis.read(bs))!=-1){
fos.write(bs,0,len);
}
fis.close();
fos.flush();
fos.close();
f.delete();
}
}
缓冲流
带有缓冲区的数据流
BufferedInputStream
BufferedOutputStream
BufferedReader 重点(其他了解就行)
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception{
// BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("a.txt")));
BufferedReader br = new BufferedReader(new FileReader(new File("a.txt")));
// System.out.println(br.readLine()); // 是读取文本文件最好用的方法
// System.out.println(br.readLine()); // 读取一行
// 标准写法
String str = "";
while ((str= br.readLine())!=null){ // 读取内容
System.out.println(str);
}
br.close();
}
}
运行结果:
BufferedWriter
转换流
字节流->字符流
InputStreamReader
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws Exception{
// 把字节流转换成字符流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
System.out.println("从System.in接受到的是:"+s);
}
}
运行结果:
OutputStreamWriter
import java.io.OutputStreamWriter;
import java.io.Writer;
public class Test2 {
public static void main(String[] args) throws Exception{
Writer writer = new OutputStreamWriter(System.out);
writer.write("你好啊");
writer.flush();
writer.close(); // 有时候,这个流不可以关,关了后续无法打印
System.out.println("看看");
}
}
运行结果:
对象流
ObjectInputStream
定义一个类
import java.io.Serializable;
public class Person implements Serializable {
private int id;
private int age;
private String name;
public Person(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class Test {
public static void main(String[] args) throws Exception{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("person.dat")));
Person p = new Person(1,18,"劲夫");
oos.writeObject(p);
oos.flush();
oos.close();
}
}
ObjectOutputStream
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class Test2 {
public static void main(String[] args) throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("person.dat")));
Object obj = ois.readObject();
Person p = (Person) obj;
System.out.println(p.getName());
}
}
运行结果:
// 出现异常 这个是没有序列化
Exception in thread "main" java.io.NotSerializableException: com.wg.io.obj.Person
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at com.wg.io.obj.Test.main(Test.java:11)
序列化:把一个对象转化成字节的过程
反序列化:把字节转换成对象
在Java中只需要给类添加一个实现 Serializable,就是可以被序列化的一个类了
文件修改操作
把文件唐诗三百首.txt,文件中的李白替换李太白
唐诗三百首
1.静夜思,李白。床前明月光,疑是地上霜。举头望明月,低头思故乡。
2.望庐山瀑布,李白。日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。
3.早发白帝城,李白。朝辞白帝彩云间,千里江陵一日还。两岸猿声啼不住,轻舟已过万重山。
结果:
唐诗三百首
1.静夜思,李太白。床前明月光,疑是地上霜。举头望明月,低头思故乡。
2.望庐山瀑布,李太白。日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。
3.早发白帝城,李太白。朝辞白帝彩云间,千里江陵一日还。两岸猿声啼不住,轻舟已过万重山。
思路:逐行读取文件中的内容,依据内容进行替换,把替换的结果记录在一个新文件里,知道数据写入完毕,把源文件删除,把新文件的名字改成源文件的名字。
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception{
File res = new File("唐诗三百首.txt");
File another = new File("副本_唐诗三百首.txt");
BufferedReader br = new BufferedReader(new FileReader(res));
BufferedWriter bw = new BufferedWriter(new FileWriter(another));
String line = "";
while ((line = br.readLine())!=null){ // 读取数据
line = line.replace("李白","李太白"); // 替换数据
bw.write(line); // 写入到新文件
bw.newLine(); // 另起一行
}
br.close();
bw.flush();
bw.close();
// 删除源文件
res.delete();
another.renameTo(res); // 重命名
}
}
练习
读取文件中的水果信息,计算水果的总价(价格*库存),并写入到文件中
fruit.txt:
名称_价格_库存
香蕉_3.33_20
苹果_1.25_10
橘子_1.33_40
结果:
名称_价格_库存_总价
香蕉_3.33_20_66.60_66.60
苹果_1.25_10_12.50_12.50
橘子_1.33_40_53.20_53.20
import java.io.*;
import java.text.DecimalFormat;
public class HomeWork {
public static void main(String[] args) throws Exception{
DecimalFormat df = new DecimalFormat(".00");
// 1 能从文件中读取水果信息
// 1.1 需要创建输入流 BufferedReader
// 1.2 第一行需要特殊处理,第一行是表头
File f1 = new File("fruit.txt");
BufferedReader br = new BufferedReader(new FileReader(f1));
File f2 = new File("副本_fruit.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(f2));
String title = br.readLine(); // 第一个行内容
// 写出第一行内容
bw.write(title+"_总价");
bw.newLine();
// 2 计算水果的总价格
// 2.1 读取所有水果信息
String content = "";
while ((content = br.readLine())!=null){
String[] fs = content.split("_");
double price = Double.parseDouble(fs[1]); // 因为是小数,转换成double
double num = Double.parseDouble(fs[2]);
double totle = price * num;
String totleSrt = df.format(totle); // "66.60"
content += "_"+totleSrt; // 拼接 香蕉_3.33_20_66.60
bw.write(content); // 向新文件写入内容
bw.newLine();
}
br.close();
bw.flush();
bw.close();
// 3 删除源文件,重命名新文件
f1.delete();
f2.renameTo(f1);
}
}