文章目录
文件类
文件:是一组相关的记录数据的集合。
Java中文件的表示:File类。可以表示为文件,也可以表示为目录。
Java中文件路径的分类:
- 相对路径:a\b\a.txt
- 绝对路径:D:\a\b\a.txt
文件类(File)的常用方法:
- 创建一个新文件:createNewFile(“路径”)
- 创建一个目录:mkdir(“路径”)
- 创建多级目录:mkdirs(“路径”)
- 判断文件/目录是否存在:exists()
- 删除文件:delete()
- 获取文件内容大小:length()
- 获取文件的相对路径:getPath()
- 获取文件的绝对路径:getAbsolutPath()
- 获取上一次修改时间:lastModified()
IO流
**流的概念 **:流是一个通道,里面是一连串的连续的字符,按照FIFO方式进行流动。(FIFO:first in first out 先进先出)
流的分类:
- 按照数据类型分:
字节流
字符流 - 按照流向分:
输入流
输出流
注意:流使用后记得关闭。否则会造成资源占用/耗费。
字节流
字节流适用于任何文件。
FileInputStream/FileOutputStream
FileInputStream/FileOutputStream:文件输入/输出流。
FileInputStream:读取文件中的数据到内存中。
FileOutputStream:将内存中的数据写入文件。
读取文件方法:read(),返回的是读取到的字节
写入数据方法:write()
方法很多,请自行查文档,太多了写不下
具体使用方法:
//将a.txt复制到b.txt
class FileStreamTest{
public static void main(String[] args){
InputStream fis = null;
OutputStream ois = null;
try {
//创建文件输入流对象,参数是文件地址,可以是相对也可以是绝对地址
fis = new FileInputStream("D:\\a\\b\\a.txt");
//创建文件输出流对象,参数是文件地址,可以是相对也可以是绝对地址
ois = new FileOutputStream("D:\\a\\b\\b.txt");
int len = 0;//用于接收read()读取的字节
while((len = fis.read()) != -1){
ois.write(len);//写入指定文件
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fis!=null){
try {
//关闭流
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois != null){
try {
//清空流
ois.flush();
//关闭流
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
DataInputStream/DataOutputStream
DataInputStream/DataOutputStream:数据输入/输出流。
数据专属的字节流。
注意:DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候需要提前知道写入的顺序。 读的顺序需要和写的顺序一致,这样才可以正常取出数据。
例如:
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data"));
//这是存的顺序
dos.writeByte(100);
dos.writeShort(1000);
dos.writeInt(10000);
dos.writeLong(100000);
dos.writeFloat(200);
dos.writeDouble(300);
dos.writeBoolean(true);
dos.writeChar('中');
DataInputStream dis = new DataInputStream(new FileInputStream("data"));
//打乱顺序就无法正常取出数据
//正常取出数据:
System.out.println(dis.readByte());
System.out.println(dis.readShort());
System.out.println(dis.readInt());
System.out.println(dis.readLong());
System.out.println(dis.readFloat());
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
System.out.println(dis.readChar());
BufferedInputStream/BufferedOutputStream
BufferedInputStream/BufferedOutputStream:缓冲字节输入/输出流。
自带缓冲区的字节流。(暂时不讲,留着字符流讲,因为使用方法都是基本一样的)
ObjectInputStream/ObjectOutputStream
ObjectInputStream/ObjectOutputStream:对象输入/输出流。
ObjectInputStream:反序列化
ObjectOutputStream:序列化
序列化:对象——>字节
反序列化:字节——>对象
注意事项:
- 序列化的对象必须实现Serializable接口
- 一个类中的属性如果也是一个类,则此属性代表的类也必须序列化。
- 当类中属性有transient关键字修饰时,此属性不参与流的传输。
- 当类中属性是static关键字修饰属性时,此属性在流中正常传输,值受最终所给的值来决定。
- 为了防止序列化版本不一致,最好手工加上serialVersionUID的编号。
案例:
//序列化
public class ObjectOutputStreamTest01 {
public static void main(String[] args) throws Exception{
//创建java对象
Student students = new Student("张三",2222);
//序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("log"));
oos.writeObject(students);
oos.flush();
oos.close();
}
}
class Student implements Serializable {
private static final long serialVersionUID = 6845409090868647L;
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"姓名='" + name + '\'' +
", 年龄=" + age +
'}';
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/*
反序列化:
*/
public class ObjectInputStreamTest01 {
public static void main(String[] args) throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("log"));
Object s = ois.readObject();
System.out.println(s);
ois.close();
}
}
字符流
字符流适用于文本类文件。用于文本文件的时候效率比字节流高。
InputStreamReader/OutputStreamWriter
InputStreamReader/OutputStreamWriter:字节流转换为字符流
使用方法基本和上面的字节流一致。
注意:这里讲一下什么是包装流什么是节点流。
例如:new OutputStreamWriter(new FileOutputStream(“d:/a/b/a.txt”,true),“utf-8”);这个代码中,外层的叫包装流,内层的叫节点流。
包装流:new OutputStreamWriter();
节点流:new FileOutputStream(“d:/a/b/a.txt”,true),“utf-8”
特点:关闭流的时候只需要关闭包装流即可。
案例:
public class Test04 {
public static void main(String[] args) {
//1.产生基本字符输出流
OutputStreamWriter osw=null;
InputStreamReader isr=null;
try {
//2.产生输出对象
osw=new OutputStreamWriter(new FileOutputStream("d:/a/b/a.txt",true),"utf-8");
isr=new InputStreamReader(new FileInputStream("d:/a/b/a.txt"));
//3.写入数据
osw.write("你好");
//4.清空
osw.flush();
//给个提示
System.out.println("写入成功!");
//3.5定义变量
char[] chars=new char[100];
int len=0; //返回的实际长度
//4.读取数据
while((len=isr.read(chars))!=-1) {
System.out.println(len);
//5.输出 char[]-->String
String str=new String(chars);
System.out.println(str);
}
}catch (Exception e) {
e.printStackTrace();
}finally {
if(osw!=null) {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(isr!=null) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileReader/FileWriter
FileReader/FileWriter:文件字符输入/出流
案例:
public class Test05 {
public static void main(String[] args) {
//1.产生字符便捷输出类
//产生字符便捷输入类
Writer writer=null;
Reader reader=null;
//2.使用try...catch
try {
//产生fileWriter对象
writer=new FileWriter("d:/a/b/a.txt",true);
//产生fileReader对象
reader=new FileReader("d:/a/b/a.txt");
//写入数据到文件
writer.write("中文");
//给个提示
System.out.println("写入成功!");
//读取数据
char[] data=new char[100];
int len=0; //返回长度
while((len=reader.read(data))!=-1) {
String str=new String(data);
System.out.println(str);
}
}catch (Exception e) {
e.printStackTrace();
}finally {
if(writer!=null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
BufferedReader/BufferedWriter
BufferedReader/BufferedWriter:缓冲字符输入/出流。
案例:
public class BufferedReaderTest01 {
public static void main(String[] args) throws Exception{
FileReader reader = new FileReader("Test01");
//这里的构造方法中要传入一个Reader
//此时对于这个程序来说:FileReader就是一个节点流。BufferedReader就是一个包装流。
BufferedReader br = new BufferedReader(reader);
//读一行 readLine();
//什么时候结束呢?
//当读到末尾时,会返回一个null
String str1 = null;
while ((str1 = br.readLine()) != null)
System.out.println(str1);
//关闭流
//对于包装流来说,只需要关闭最外层流就行,里面的节点流会随着关闭。(看底层源代码)
br.close();
}
}
public class BufferedWriterTest01 {
public static void main(String[] args) throws Exception{
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Test03",true)));
bw.write("Hello Kitty");
bw.write("\n");
bw.write("Hello King");
bw.flush();
bw.close();
}
}
这里实际上不推荐使用BufferedWriter,推荐使用的是PrintWriter(打印字符流)。
案例:
public class Test07 {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
//1.产生字符输出流
PrintWriter pw=new PrintWriter(new FileOutputStream("d:/a/b/a.txt",true),true);
//2.写数据
pw.println("这是打印字符流,我很喜欢使用,哈哈3!");
//3.给个提示
System.out.println("写入成功!");
//4.清空
pw.flush();
}
}
PrintStream
PrintStream:打印字节流
作用:改变输出的显示位置
其实我们常用的:System.out 也是一个打印字节流。查看文档可知。
/**
* 使用PrintStream流改变输出的显示位置,结果存在文件中
*/
public class Test08 {
public static void main(String[] args) throws FileNotFoundException {
//System.out返回的是PrintStream
//我们可以尝试不写System.out,改为我们喜欢的方式来进行输出
PrintStream ps = System.out;
ps.println("Hello zhangsan");
ps.println("Hello lisi");
ps.println("Hello king");
PrintStream ps=new PrintStream("d:/a/b/a.txt");
//改变输出位置
System.setOut(ps);
//打印输出
System.out.println("这是测试PrintStream流,我已经改变了它的显示位置,我是否可以当一黑客了!");
System.out.println("写入完毕!");
/*
关闭流
实际上标准输出流不需要手动close()关闭
想想,我们使用System.out关闭过吗?
*/
ps.close();
}
}
IO流+Properties的联合使用
以后经常改变得数据,可以单独写道一个文件中,使用程序动态提取。将来只需要修改这个文件得内容,java代码不需要改动,不需要重新编译, 服务器也不需要重启就可以拿到动态信息。
类似于以上机制的这种文件,被称为配置文件。并且当配置文件的格式是键值对的时候,我们把这种文件叫做属性文件。
例如:
key1=value
key2=value
key3=value
java规范中有要求:属性配置文件建议以properties结尾。但不是必须这样。
这种以.properties结尾的文件在java中被称为:属性配置文件
其中Properties对象是专门存放属性配置文件内容的一个类。
注意:
- 在属性配置文件中井号#表示注释
- 在属性配置文件中相同的key值重复value会被覆盖
- 最好不要有空格
案列:
public class IoPropertiesTest01 {
public static void main(String[] args) throws Exception{
//创建一个输入流对象
FileInputStream fis = new FileInputStream("IoPropertiesTest01");
//创建Properties对象的同时会创建一个Map集合
Properties p = new Properties();
//调用Properties中的load方法,会将文件中的数据加载到Map集合中。
p.load(fis);//文件中的数据顺着管道加载到Map集合中,其中等号(冒号也行,但不建议)左边赋值给key,右边赋值给value。
//能不能通过key获取value呢?;
System.out.println(p.getProperty("password"));
}
}
结果:
今天就到这里。拜拜~如有错误请指出,不胜感激