java基础一(文件与io流)

(七)、java基础(文件与IO流)
IO流:用于处理设备上数据。在流中一般以字节的形式存放着数据!
流:可以理解数据的流动,就是一个数据流。IO 流最终要以对象来体现,对象都存在
IO 包中。
流也进行分类:
1:输入流(读)和输出流(写)。
2:因为处理的数据不同,分为字节流和字符流。

字节流:处理字节数据的流对象。设备上的数据无论是图片或者 dvd,文字,它们都以
二进制存储的。二进制的最终都是以一个 8 位为数据单元进行体现,所以计算机中的最
小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可
以处理字符数据。

字符流:因为字符每个国家都不一样,所以涉及到了字符编码问题,那么 GBK 编码的中文用 unicode 编码解析是有问题的,所以需要获取中文字节数据的同时+ 指定的编码表才可以解析正确数据。为了方便于文字的解析,所以将字节流和编码表封装成对象,这个对象就是字符流。只要操作字符数据,优先考虑使用字符流体系。
注意:流的操作只有两种,读和写

流的体系因为功能不同,但是有共性内容,不断抽取,形成继承体系。该体系一共有四
个基类,而且都是抽象类。
字节流:InputStream OutputStream
字符流:Reader Writer

读写文件
下图是输入流和输出流的结构层次
java基础一(文件与io流)

字节流读写文件:

普通输入输出字节流读写
FileOutputStream三个write()方法
public void write(int b):写一个字节。
public void write(byte[] b):写一个字节数组。
public void write(byte[] b,int off,int len):写一个字节数组的一部分。
FileInputStream两种读取方式
int read(): 一次读取一个字节。
int read(bytes[] b) : 一次读取一个字节数组。

使用示例(复制文件)
字节流一次读一个字节:

 public static void main(String[] args) throws IOException{
    long start = System.currentTimeMillis();
    //创建对象
    FileInputStream fis = new FileInputStream("E://io流.png");
    FileOutputStream fos = new FileOutputStream("F://io流.png");
    //一次读取一个字节
    int by = 0;
    while ((by = fis.read()) != -1){
        fos.write(by);
    }
    //释放资源
    fos.close();
    fis.close();
    long end = System.currentTimeMillis();
    long gong = end - start;
    System.out.println("用了多少毫秒:"+gong);  //1565毫秒
}

一次读一个字节数组:

public static void main(String[] args) throws IOException{
long start = System.currentTimeMillis();
    //创建对象
    FileInputStream fis = new FileInputStream("E://io流.png");
    FileOutputStream fos = new FileOutputStream("F://io流.png");
    //一次读一个数组
    byte[] bytes = new byte[1024];
    int len = 0;
    while((len = fis.read(bytes)) != -1){
        fos.write(bytes,0,len);
    }
    //释放资源
    fos.close();
    fis.close();

    long end = System.currentTimeMillis();
    long gong = end - start;
    System.out.println("用了多少毫秒:"+gong); //4毫秒
}

缓冲输入输出字节流读写
相同方式使用缓冲流读写效率较高,常用的文件读写操作使用这种方式。(一次读取一个字节数组的效率远高于一次读一个字节)
BufferedInputStream读取数据,BufferedOutputStream写出数据
使用示例
一次读取一个字节:

public static void main(String[] args) throws IOException{

    //开始时间
    long start = System.currentTimeMillis();
    //创建缓存流对象
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E://io流.png"));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E://io流.png"));

    //一次读取一个字节
    int by = 0;
    while ((by = bis.read()) != -1){
        bos.write(by);
    }
    //释放缓存
    bos.close();
    bis.close();
    long gong = System.currentTimeMillis()-start;
    System.out.println("共用时间:"+gong); //21毫秒
}

一次读取一个字节数组:

 public static void main(String[] args) throws IOException{

    //开始时间
    long start = System.currentTimeMillis();
    //创建缓存流对象
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E://io流.png"));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F://io流.png"));
    //一次读取一个字节数组
    byte[] bytes = new byte[1024];
    int len = 0;
    while((len = bis.read()) != -1){
        bos.write(bytes,0,len);
    }
    long gong = System.currentTimeMillis() - start;
    System.out.println("共用时间"+gong); //35毫秒
    }

字符流出现的原因:
由于字节流操作中文不是特别方便,所以,java就提供了字符流。
字符流: 字符流 = 字节流 + 编码表。
转换流(OutputStreamWriter、InputStreamReader)

public static void main(String[] args) throws IOException{
    //创建输入流对象
    InputStreamReader isr = new InputStreamReader(new FileInputStream("E://io流.png"));
    //创建输出流对象
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("F://io流.png"));
    //复制文件
    //一次读取一个字符
   /* int ch = 0;
    while ((ch = isr.read()) != -1){
        osw.write(ch);
    }*/
    //一次读取一个字符数组
    char[] ch = new char[1024];
    int len = 0;
    while ((len = isr.read()) != -1){
        osw.write(ch,0,len);
    }
    osw.close();
    isr.close();

}

高效流(FileWriter,FileReader)

 public static void main(String[] args) throws IOException{
    //创建对象
    BufferedReader br = new BufferedReader(new FileReader("E://io流.png"));
    BufferedWriter bw = new BufferedWriter(new FileWriter("F://io流.png"));
    //一次读取一个字符数组
    char [] ch = new char[1024];
    int len = 0;
    while ((len = br.read()) != -1){
        bw.write(ch,0,len);
    }
    bw.close();
    br.close();
    }

缓存流(BufferWriter,BufferReader)

	 public static void main(String[] args) throws IOException{
    long start = System.currentTimeMillis();
    BufferedReader br = new BufferedReader(new FileReader("E://io流.png"));
    BufferedWriter wr = new BufferedWriter(new FileWriter("F://io流.png"));
    //一次读取一行
    String line = null;
    while ((line = br.readLine()) != null){
        wr.write(line);
        wr.newLine();
        wr.flush();
    }
    //释放资源
    wr.close();
    br.close();
    long gong = System.currentTimeMillis()-start;
    System.out.println("共用时间"+gong);
}

文件类
File类方法:
1、createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false。
2、mkdir() 在指定位置创建一个单级文件夹。
3、mkdirs() 在指定位置创建一个多级文件夹。
4、renameTo(File dest)如果目标文件与源文件是在同一个路径下,那么renameTo的作用是重命名, 如果目标文件与源文件不是在同一个路径下,那么renameTo的作用就是剪切,而且还不能操作文件夹。

删除:
1、delete() 删除文件或者一个空文件夹,不能删除非空文件夹,马上删除文件,返回一个布尔值。
2、deleteOnExit()jvm退出时删除文件或者文件夹,用于删除临时文件,无返回值。
判断:
1、exists() 文件或文件夹是否存在。
2、isFile() 是否是一个文件,如果不存在,则始终为false。
3、isDirectory() 是否是一个目录,如果不存在,则始终为false。
4、isHidden() 是否是一个隐藏的文件或是否是隐藏的目录。
5、isAbsolute() 测试此抽象路径名是否为绝对路径名。
获取:
1、getName() 获取文件或文件夹的名称,不包含上级路径。
2、getAbsolutePath()获取文件的绝对路径,与文件是否存在没关系
3、length() 获取文件的大小(字节数),如果文件不存在则返回0L,如果是文件夹也返回0L。
4、getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回null。
5、lastModified()获取最后一次被修改的时间。

文件夹相关:
1、static File[] listRoots()列出所有的根目录(Window中就是所有系统的盘符)
2、list() 返回目录下的文件或者目录名,包含隐藏文件。对于文件这样操作会返回null。
3、listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。对于文件这样操作会返回null。
4、list(FilenameFilter filter)返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。
5、listFiles(FilenameFilter filter)返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。

遍历目录下的文件夹:
递归遍历

	 //递归遍历
public static void floderList(String path) {
    File file = new File(path);
    if (file.exists()) {
        File[] files = file.listFiles();
        if (null == files || files.length == 0) {
            System.out.println("文件夹是空的!");
            return;
        } else {
            for (File file2 : files) {
                if (file2.isDirectory()) {
                    System.out.println("文件夹:" + file2.getAbsolutePath());
                    floderList(file2.getAbsolutePath());
                } else {
                    System.out.println("文件:" + file2.getAbsolutePath());
                }
            }
        }
    } else {
        System.out.println("文件不存在!");
    }
}