java学习笔记-File类与IO流

本文详细介绍了Java中的File类,包括如何创建File对象、文件操作以及路径处理。同时,深入讲解了Java IO流的概念,字节流与字符流的分类、使用方法,以及缓冲流、字符流、标准输入输出流、打印流和对象序列化流的使用。此外,还提到了Properties类在处理属性列表时与IO流的结合。
摘要由CSDN通过智能技术生成

File类与IO流

一.File类

File类提供了对文件的操作接口,Java中万事万物都是对象,文件也有它相应的类。

  • File是文件和目录路径名的抽象表示。
  • 文件和目录可以通过File封装成一个对象
  • File封装的不是一个真实存在的文件,仅仅是一个路径而已,对应该路径的文件可以存在,也可以不存在

1 创建一个File对象

//1.通过路径名称字符串创建
File f1 = new File("D:\\IO\\a.jpg");
//2.通过父路径名称字符串和子路径名称字符串创建
File f2 = new File("D:\\IO","a.jpg");
//3.通过父抽象路径名和子路径名称字符串创建
File parent = new File("E:\\IO");
File f3 = new File(parent,"a.jpg");

2 通过File对象创建真实的文件

createNewFile() //创建一个空文件,前提是父路径存在,且在该路径不含具有该名称的文件
mkdir()	//创建由此抽象路径名命名的目录
mkdirs()//创建由此抽象路径名命名的目录,包括任何必须但不存在的父目录

//路径分隔符
//windows下使用
 File  f1 = new File("D:\\IO\\java.txt");
 //Linux下使用
 File  f2 = new File("D:/IO/JavaSE");
 //通用,File.separator会自动转换成所属操作系统的路径分隔符
 File f3 = new File("D:" + File.separator+"IO"+File.separator+"JavaWeb"+File.separator+"HTML");

3 File类的判断和获取功能

exists()  //测试此抽象路径名表示的文件或目录是否存在。
isAbsolute()  //测试这个抽象路径名是否是绝对的。
isDirectory()  //测试此抽象路径名表示的文件是否为目录。
isFile()  //测试此抽象路径名表示的文件是否为普通文件。
isHidden()  //测试此抽象路径名命名的文件是否为隐藏文件。
getAbsolutePath()   //返回此抽象路径名的绝对路径名字符串。
getName()   //返回由此抽象路径名表示的文件或目录的名称。
getParent()   //返回此抽象路径名的父 `null`的路径名字符串,如果此路径名未命名为父目录,则返回null。
getParentFile()   //返回此抽象路径名的父,或抽象路径名 `null`如果此路径名没有指定父目录。
getPath()   //将此抽象路径名转换为路径名字符串
list() //返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录
listFiles()   //返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。

4 File类的删除功能和重命名功能

delete()   //删除由此抽象路径名表示的文件或目录。
renameTo(File) //将当前文件重命名到 File所表示的抽象路径中

注意:1.只能删除文件和空目录,若目录不为空,则删除失败
2.用该方法删除的文件和目录不会进入回收箱
3.renameTo 方法还可以实现对文件的移动

二.IO流

流:是一个抽象的概念,是对数据传输的总称
IO流是用来处理设备间数据传输问题的
input:指的是将磁盘 硬盘 其他的外部存储设备上的文件 读入到内存
output: 指的是将内存的数据输出到外部存储设备

1 IO流的分类

按数据类型,可以分为字节流(InputStream和OutputStrean)和字符流(Reader和Writer)
按流的方向,可分为输入流和输出流
若操作的是纯文本文件,优先使用字符流
若操作的图片 音频 视频等二进制文件 优先使用字节流
如果不能确定文件的类型,推荐使用字节流,字节是万能的

2 字节流的使用

InputStream是所有字节输入流的抽象父类
OutputStream是所有字节输出流的抽象父类

子类的命名都是以InputStream/OutputStream 结尾的 常用的子类 FileInputStream

2.1 输出字节流的基本方法

//输出字节流可以用路径字符串或抽象路径 来指定要写入的文件
FileOutputStream(File file)
FileOutputStream(String name)
FileOutputStream(File file,  boolean append)  //append为true时表示在文件的末尾追加数据(在同一个字节流对象中时)
FileOutputStream(String name,  boolean append)
//写入的方法,可以写入字节数组,或单个字节
write(byte[] b)
write(byte[] b,  int off, int len)
write(int b)

close()  //关闭此文件输出流并释放与此流相关联的任何系统资源。

注意在不同操作系统中表示换行的字符是不同的: windowns: \r\n linux: \n max: \r

2.2 字节流写输出的异常处理

public class OutputStreamDemo2 {
    public static void main(String[] args) {
        OutputStream os = null;
        try{
            os = new FileOutputStream("day_12/dir/fos.txt");
            os.write("hello".getBytes(StandardCharsets.UTF_8));
        }catch (FileNotFoundException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
           if(os != null){//只有当字节输出流不为空才关闭
               try {
                   os.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
        }
    }
}
2.3 字节输出流的基本方法
FileInputStream(File file)
FileInputStream(String name)
//读取一个字节,或字节数组长度,返回读入缓存区的总字节数,当读取到文件末尾时,返回-1
read()
read(byte[] b)
read(byte[] b,  int off, int len) 

两种读取方式

        InputStream is = new FileInputStream("day_12/dir/fos.txt");
        int i ;
        while( (i = is.read()) != -1){
            System.out.print((char)i);
        }
        is.close();
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("day_12/dir/fos.txt");
        byte[] bytes = new byte[1024];//1KB
        int len;// 每次读取到缓冲区的字节数
        while((len = is.read(bytes)) != -1){
            //String(byte[] bytes, int offset, int length, String charsetName)
            //构造一个新的 String通过使用指定的字符集解码指定的字节子阵列。
            System.out.print(new String(bytes,0,len,"UTF-8"));
        }
        is.close();
    }

2 字节缓冲流

字节缓冲流有BufferedInputStream和BufferedOutputStream两种,它们会创建一个指定大小的缓冲区;数据在传输过程会先进入缓冲区暂存,然后一次性将缓冲区的数据读出或写入目标文件
//创建字节缓冲流需要提供底层字节流
BufferedOutputStream(OutputStream out, int size)
BufferedInputStream(InputStream in, int size)

注意事项:BufferedOutputStream会先把数据写到缓冲区,缓冲区写满时,才会将缓冲区的内容写出到磁盘
可以通过flush方法刷新缓存流,将缓冲区的内容写入磁盘,它不会释放资源
close方法,在关闭流,释放资源之前,会先刷新缓冲流

为什么缓冲流的构造方法需要的是一个字节流,而不是具体的文件或路径呢?
字节流仅仅提供缓冲区,而真正的读写数据离不开基本字节流对象进行操作

3 字符流

介绍:

  • 字符流 = 字节流+字符集
  • 由于字节流操作中文不是特别方便,所以出现了字符流
  • 汉字在存储的时候无论使用哪种编码格式存储,第一个字节都是负数
  • 用字节流赋值文本文件时,文本文件也会有中文,但没问题,因为最终底层操作会自动进行字节拼接成中文。

字符串的编码和解码问题:

//使用编码集将字符串编码为字节序列
 byte[] getBytes()   //默认是UTF-8
 byte[] getBytes(String charsetName)
//使用编码集将字节序列解码为字符串
`String(byte[] bytes,  String charsetName)`

字符流的类和方法:

Reader  Writer //字符输入流和字符输出流的抽象基类
InputStreamReader     OutputStreamWriter//是字符流和字节流的桥梁,会使用指定字符集编码或解码字节流

//构造方法有:
OutputStreamWriter(OutputStream out) //使用默认字符集
OutputStreamWriter(OutputStream out, String charsetName)
InputStreamReader(InputStream in) //使用默认字符集
InputStreamReader(InputStream in, String charsetName)

写入单个字符,字符数组,或字符串
write(char[] cbuf,  int off, int len)
write(int c)
write(String str,  int off, int len)
write(String str)
write(char[] cbuf)

刷新和关闭,字符流自带缓冲区
close()  //关闭流,先刷新
flush()  //刷新流
读取单个字符或字符数组,到达文件末尾返回-1
read()
read(char[] cbuf,  int offset, int length)
read(char[] cbuf)
//创建实例
Reader  r = new InputStreamReader(new FileInputStream("txt"));
Writer w = new OutputStreamWriter(new FileOutputStream("txt"));
字符流操作的便捷类:FileReader   FileWriter  
Reader r = new FileReader("day");
Writer w = new FileWriter("day");

字符缓冲流
BufferedReader BufferedWriter

String readLine()  //读一行文字,到文件末尾返回null(不保存回车符)
void newLine()  //写行分隔符
flush()     close()  
write()      //可以写入字符数组,单个字符或字符串

3.标准输入输出流

static PrintStream   err  //标准”错误输出流
static InputStream in  //  标准”输入流。  默认指的键盘
static PrintStream  out   //标准”输出流。  默认是屏幕
InputStream is = System.in;
InputStreamReader isr = new InputStreamReader(is);  //将字节流转换成字符流

4.打印流

  • 字节打印流 PrintStream
  • 字符打印流 PrintWtriter
  • 特点:只负责数据的输出,不能读数据 有一些特有的方法
PrintStream(File file)  //使用抽象路径名创建
PrintStream(OutputStream out)  //使用已有的字节流创建
PrintStream(String fileName)  //使用路径名字符串创建
print()
println()
append()
PrintWriter操作方法类似PrintStream

5.对象的序列化流

对象序列化: 就是将对象保存到磁盘或者在网络中传输对象 为了对象保存的正确性 和传输的安全性,需要对对象进行编码处理,那么把这种处理方式称为对象的序列化
反序列化:将序列化的对象解析为原对象的过程 就称为反序列化

  • ObjectOutputStream
  • ObjectInputStream
    传输对象必须实现java.io.Serializable接口
public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day_13/dir/oos.txt"));
        //创建学生对象
        Student stu1 = new Student("张三",22);
        oos.writeObject(stu1);//写出一个对象
        oos.close();
        // 反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day_13/dir/oos.txt"));
       Object obj =  ois.readObject();
       Student stu = (Student) obj;
        System.out.println(stu);
    }

6.Porperties

Porperties是Map集合的一个实现类
Porperties可以保存到流中或者从流中加载。 属性列表中的键及其对应的值都是字符串

Porperties和IO流结合的方法

load(InputStream inStream)   //从输入字节流读取属性列表(键和元素对)
load(Reader reader)   //从输入字符流读取属性列表(键和元素对)
store(OutputStream out, String comments) //将此属性列表(键和元素对)写入此 Properties表中
store(Writer writer, String comments)	//将此属性列表(键和元素对)写入此 Properties表中
public class ProPertiesDemo {
    public static void main(String[] args) throws IOException {
       // myLoad();
        myStore();
    }
    public static void myLoad() throws IOException {
        Properties prop = new Properties();
        Reader r = new FileReader("day_13/dir/test.properties");
        prop.load(r);
        r.close();
        System.out.println(prop.get("username"));
    }
    public static void myStore() throws IOException {
        Properties prop = new Properties();
        prop.setProperty("001","张三");
        prop.setProperty("002","李四");
        prop.setProperty("003","王五");
        prop.setProperty("004","admin");
        FileWriter fw = new FileWriter("day_13/dir/test.properties");
        prop.store(fw,"这是存储一些对象");
        fw.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值