File类/IO流介绍

一. File

概要:实现将数据从内存中存储到计算机硬盘中,存储方式以File的形式进行存储
File是Java.io包下的类,File类对象既可表示文件,又可表示文件夹
File类只能对文件本身进行操作,不能读写文件里存储的数据,想要操作文件里的数据需要用到io流

1.1 文件的创建

  • 文件的创建File类/IO流介绍_第1张图片

  • File文件的相对路径File类/IO流介绍_第2张图片 - 遍历文件
    -

相对路径可以方便文件管理,避免存储到其他盘符,找不到文件

遍历文件夹
1.一级文件夹遍历

#修改文件名
#listFiles只能遍历文件夹下一级目录的内容
 public static void main(String[] args)
    {
        File file=new File("D:\\works");
        File[] files = file.listFiles();

        for(File f:files)
        {
            String name = f.getName();
            String end = name.substring(name.lastIndexOf("."));
            UUID uuid = UUID.randomUUID();
            f.renameTo(new File(file,uuid+end));
        }
    }

2.遍历文件夹下的所有内容—方法递归

  • 概念:方法自己调用自己的形式,就叫方法递归。
    直接递归,方法内部调用自己;间接递归,方法调用其他方法,其他方法回调自己方法

  • 方法递归需要控制终止,不然会进入死循环,导致栈中的方法溢出

  • 递归算法的三要素,递归公式:f(n)=f(n-1)*n,递归的终结点:f(1),递归的方向必须走向终结点

    //递归累加
     public static void main(String[] args)
        {
            System.out.println(sum(10));
        }
        public static int sum(int i)
        {
            if (i==1)
            {
                return i;
            }
            else
            {
                return sum(i-1)+i;
            }
        }
    

    经典案例:猴子吃桃

     	/**
          * 猴子吃桃的问题
          * 第一天,吃了一半,又多吃了一个;第二天,吃了一半,又多吃了一个....10天后只剩一个了,求桃子的总数
          */
         public static int test1(int i) {
              # 根据天数建立方程
        		  f(x)-f(x)/2-1=f(x+1)------->f(x)=2f(x+1)+2
               第一天的桃减去吃掉的一半多一个等于第二天的桃子
           
             if(i==10)
             {return 1;}
             else
             {return 2*test1(i+1)+2;}}
     	```
    
    //根据文件名称查找文件位置-----递归的运用
    public class File2 {
    public static void main(String[] args) throws IOException {
     fileSearch(new File("F:\\网易云"),"网易云.exe");
    }
    
    public static void fileSearch(File dir,String name) throws IOException {
        if (!dir.exists()|| dir.isFile()||dir==null)
        {
            return;
        }
        File[] files = dir.listFiles();
        if (files.length>0&&files!=null)
        {
            for (File f:files)
            {
                if (f.isFile())
                {
                    if (f.getName().contains(name))
                    {
                        System.out.println("找到了"+f.getAbsolutePath());
                        Runtime runtime=Runtime.getRuntime();
                        runtime.exec(f.getAbsolutePath());
                    }
                }
                else 
                {
                    fileSearch(f,name);
                }
            }
        }
    }
    

}
```

File类的常见方法,可以参考Java开发文档

二. IO流-字节流

2.1流的基本概念

io流:用于读写数据,可以读写文件,或者网络中的数据

按照流的方向可分为

  • 输入流:将磁盘文件或者网络文件读取到内存中
  • 输出流:将内存中的数据保存到磁盘

按照流中的最小数据单位可分为

  • 字符流 :适合操作纯文本,例如txt、java文件
  • 字节流:适合所有文件,例如音频、视频、图片、文本文件的复制转移等

IO流的分类

File类/IO流介绍_第3张图片1.字节输入流
2.字节输出流
3.字符输入流
4.字节输出流

2.2 InputStream

字节输入流,将文件输入到内存,该类是接口类,实现类是FileInputStream

  • read()无参方法,一次读取一个字节

    #InputStream的创建 InputStream stream=new FileInputStream(new File("具体文件的路径")) int b; while((b=stream.read())!=-1) {
    System.out.print((char)b);//InputStream 存储的是字节流,所以,必须转换为字符集 }
    //read()无参方法只能逐个读取,会占用更大量的系统资源,且使用完毕需要关闭流,close()方法
    //read()方法,当字节流读取完所有的字节后,会返回-1 ```
    
  • read( byte[ ] b)有参方法,一次读取多个字节

    //read(byte[] buffer),一次性读取多个字节,性能高,但是读取汉字会出现乱码
    InputStream stream=new FileInputStream(new File("具体文件的路径"))
    byte[] buffer=new byte[3];
    int len=stream.read(buffer);//将读取到的字节放入buffer数组,返回数为读取到的数值总数,读取到的内容不能超过数组长度。
    String str=new String(buffer,0,len);//buffer数组,从第0位开始,读取len长度的数据转为字符串
    
    int len=stream.read(buffer);//当多次向同一个字节数组添加数据时,且字节数组长度不够用,后者会覆盖前者
    
  • 一次读取所有字节

    //1.定义一个和文件大小一样的字节数组,存放数据
    InputStream is=new FileInputStream("文件地址");
    File f=new File("文件地址");
    long size=f.length();
    byte[] buffer=new byte[(int) size];
    is.read(buffer);
    //2.调用readAllBytes方法直接读取所有的
    InputStream is=new FileInputStream("文件地址");
    byte[] buffer=is.readAllBytes();
    System.out.print(new String(buffer));
    
    

字节输入流的缺点,如果文件过大,会出现内存溢出

2.3 OutputStream

将内存中的数据写到文件中,该类为接口类,实现类为FileOutputStream

//通过io流复制文件
  InputStream inputStream=new FileInputStream("D:\\works\\test3\\1.jpg");//读取文件流
  OutputStream outputStream=new FileOutputStream("D:\\test1\\test2\\2.jpg");//写入文件流,文件名必须自取
  long i = new File("D:\\works\\test3\\1.jpg").length();//获取文件字节数
  byte[] bytes=new byte[(int) i];//创建对应长度的字节数组
  int len;
  inputStream.read(bytes);//读文件,将读取的数据放入字节数组
  outputStream.write(bytes);//写文件,将数组中的文件写道指定的文件夹中
  outputStream.close();
  inputStream.close();

2.4 IO流资源的释放

try
{//执行语句
}
catch(Exception e)
{//语句出现异常捕获异常
}
finally
{//不管语句正确与否,一定会执行
}

需要注意的是,不能在finall方法体内输入return,不然try方法体就不能执行了
try…catch…finally
File类/IO流介绍_第4张图片
try-with-resource
File类/IO流介绍_第5张图片

File类/IO流介绍_第6张图片
将连接的流资源放在try的小括号内,去掉原有的finally,当调用完成,方法会自动释放关闭流
底层原理,输入输出流实现了Closeable接口,只要实现了该接口就能算作资源类,且Closeable中定义了资源关闭方法close(),所以当使用try-catch-resource时,资源使用完毕后会自动释放

3.IO流–字符流

File类/IO流介绍_第7张图片
字符输入流-FileReader,原理和字节输入流一致,只是读取的每个数据都会被当作字符看待
File类/IO流介绍_第8张图片
字符输出流常用的方法
File类/IO流介绍_第9张图片
File类/IO流介绍_第10张图片
注意:字符输出流写出数据后,必须刷新,或者关闭流,写入的数据才能生效
flush()方法进行刷新;close()关闭后等于自动刷新

4.缓冲流

4.1字节缓冲流

原理:字节缓冲输出输入流自带了8KB缓冲池,字节缓冲流每读写一次,就往缓冲池放入8KB的字节,使用缓冲流是为了提高读写的性能,缓冲池在内存中,内存读写的效率比外存高
File类/IO流介绍_第11张图片

// 缓冲字节流拷贝视频,视频、音频等资源文件需要用字节流读写
public static void test2()
    {
        
        try (
              BufferedInputStream bufferedInputStream= new BufferedInputStream(new FileInputStream("D:\\电影直播\\video_230801_192356.mp4"));
              BufferedOutputStream outputStream= new BufferedOutputStream(new FileOutputStream("D:\\电影直播\\1.mp4"));
        )
        {
            long start = System.currentTimeMillis();
            long ln=0;
            byte [] bytes=new byte[1024];
            while ((ln=bufferedInputStream.read(bytes))!=-1)
            {
                outputStream.write((int) ln);
            }
            long end = System.currentTimeMillis();
            System.out.println((end-start)/1000+"s");

        }catch (Exception e)
        {

        }
    }

简单字节流和缓冲字节流,在调用有参字节的读写时,字节数组长度越大,读写性能越好

4.2字符缓冲流

作用:提高字符流的读写效率,自带8KB的缓冲池,缓冲池在内存中,字符缓冲流每读写一次,就往缓冲池放入8KB的字符,内存读写的效率比外存高

字符缓冲输入流

  • 创键字符缓冲输入流File类/IO流介绍_第12张图片
  • BufferedReader类提供了一个特有的方法,读取一行字符,readLine(),没有值时就返回null

字符缓冲输出流

  • public BufferedWriter(Writer r),把低级字符输出流包装成一个高级的缓冲字符输出流管道,提高字符流写的效率
  • 字符缓冲输出流新增的功能:换行,public void newLine()
    File类/IO流介绍_第13张图片

5. IO流-转换流

如果代码编码和被读取的文本文件的编码是不一致的,使用字符流读取的文本文件会出现乱码
解决方法:字符转换流
File类/IO流介绍_第14张图片

5.1字符输入转换流—InputStreamReader

//解决乱码的思路
1.先将拿到文件的字节流,然后通过字符转换流的构造方法,将字节流的编码格式改成文件对应的编码格式,如GBK
public InputStreamReader(InputStream is,String charset)

例如:
InputStream is=new FileInputStream("文件地址");
Reader isr=new InputStreamReader(is,"GBK");
BufferReader br=new BufferReader(isr);

5.2 字符输出转换流

//实现的思路
1.拿到原始的字节输入流
2.通过字符输出转换流的构造方法,传入字节流,并将字符输出流编码格式改成需要的格式
public OutputStreamWrite(OutputStream os,String charset)

案例
OutputStream os=new FileOutputStream("文件地址");
Writer osw=new OutputStreamWriter(os,"GBK");
BufferWrite bw=new BufferWriter(osw);
bw.write("123你好");
//写入后要生效的话记得关闭流或刷新流

6.打印流

6.1PrintStream,字节打印流

File类/IO流介绍_第15张图片
构造器和方法
File类/IO流介绍_第16张图片

6.2PrintWriter,字符打印流

File类/IO流介绍_第17张图片

6.3 流的重定向

System.out.println()就是采用打印流的放法,将数据输出在控制台

PrintStream ps=new PrintStream("文件路径");
System.setOut(ps);
//输出的内容被重定向到指定的文件路径中

7.IO流-数据流

用于通信,可以存储数据的类型,根据类型读取数据File类/IO流介绍_第18张图片
File类/IO流介绍_第19张图片
需要注意的是,读取数据的时候,需要按照数据类型的排序进行读取
File类/IO流介绍_第20张图片

8.IO流-序列化流

将java对象写入到文件中,即序列化。将java对象读取出来,即反序列化
如果想要一次性序列化多个对象的话,直接对集合进行序列化即可,ArrayList集合已经实现了序列化接口
序列化

  • 需要自定义一个类,并实现序列化接口Serializable
  • 序列化流的创建
    在这里插入图片描述
  • 将序列化文件写入oss.writeObject(new User("张三",23,"男"))

反序列化

File类/IO流介绍_第21张图片
在进行序列化的时候,某个熟悉不想被展示出来,可以用transient修饰属性,这样该属性就不会参与反序列化

9.IO流-io框架(重点)

Commons-io框架,用框架可以直接省略以上的所有内容
File类/IO流介绍_第22张图片
File类/IO流介绍_第23张图片

你可能感兴趣的:(IO流,java)