关于Java的File类字节流和字符流

Posted 古兰精

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Java的File类字节流和字符流相关的知识,希望对你有一定的参考价值。

一、File类:

  在Windows下的路径分隔符(\)和在Linux下的路径分隔符(/)是不一样的,当直接使用绝对路径时,跨平台会报No Such file or diretory异常。

  File中还有几个与separator类似的静态常量,与系统有关,在编程中应尽量使用。

  ps:File file = new File("G:"+ File.separator +"demo.txt");

  File类是java.io包中唯一一个与文件本身操作有关的类,文件本身操作是指文件的创建、删除、重命名等。

  .构造方法:public File(String pathName),传入完整的路径,WEB开发此方式比较好用。

  .构造方法:public File(File parent,String child),传入父路径和子路经。

  基本的文件操作:

  .创建新文件:public boolean createNewFile() throws IOException;

  .删除文件:public boolean delete();

  .判断文件是否存在:public boolean exists();

import java.io.File;
import java.io.IOException;
public class TestFile {
    public static void main(String [] args) throws IOException{
        File file = new File("G:\\demo.txt");
        System.out.println("file:"+file);
        if(file.exists()){
            file.delete();
            System.out.println("执行了删除文件!");
        }else{
            file.createNewFile();
            System.out.println("执行了创建文件");
        }
    }
}

  如果进行文件创建时有目录,则需要先创建目录之后才可以创建文件。

  .找到父路径:public File getParentFile();

  .创建目录:(1)public boolean mkdirs();既可以在不存在的目录中创建文件夹,又可以创建多级目录(个人推荐使用此方法)

        (2)public boolean mkdir();只能在已经存在的目录中创建文件夹

import java.io.File;
import java.io.IOException;
public class TestFile {
    
    public static void main(String [] args) throws IOException{
        File file = new File("G:"+ File.separator +"Test"+ File.separator +"TestFile"+ File.separator +"demo.txt");
        if(!file.getParentFile().exists()){//文件不存在
            file.getParentFile().mkdirs();
            System.out.println("执行了创建多级目录");
        }
        if(file.exists()){//文件存在
            file.delete();
            System.out.println("执行了删除文件!");
        }else{
            file.createNewFile();
            System.out.println("执行了创建文件");
        }
    }
}

  除了上述基本的文件和文件夹的操作之外,还提供了一些取得文件信息的方法:

    .判断路径是否是文件:public boolean isFile();

    .判断路径是否是文件夹:public boolean isDirectory();

    .最后一次修改时间:public long lastModified();

    .取得文件大小:public long length();

    .修改文件名称:public boolean renameTo(File dest);

import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
public class TestFileOne {
    public static void main(String [] args){
        File file = new File("G:"+ File.separator +"Test"+ File.separator +"TestFile"+ File.separator +"1.jpg");
        if(file.exists()){
            System.out.println(file.isDirectory()? "是文件夹" : "不是文件夹");
            System.out.println(file.isFile() ? "是文件" : "不是文件");
            System.out.println("最后修改时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified()));
            System.out.println("文件大小:"
                    + new BigDecimal((file.length() / (double) 1024 / 1024))
            .divide(new BigDecimal(1), 2,BigDecimal.ROUND_HALF_UP) + "M");
            
            if(file.renameTo(new File("G:"+ File.separator +"Test"+ File.separator +"TestFile"+ File.separator +"hello.jpg"))){
                System.out.println("重命名成功");
            }else{
                System.out.println("重命名失败");
            }
        }
    }
}

  列出指定文件夹中的所有内容:

    public File [] listFiles();

import java.io.File;
public class TestFileTwo {
    public static void main(String [] args){
        File file = new File("G:" + File.separator + "Test");
        if(file.exists() && file.isDirectory()){
            File [] list = file.listFiles();
            for(int i = 0; i < list.length; i ++){
                System.out.println("files:"+list[i]);
            }
        }
    }
}

  列出指定目录中的所有文件(包含所有子目录中的文件),递归调用

import java.io.File;
public class TestFileThree {
    public static void main(String [] args){
        File file = new File("G:" + File.separator + "Test");
        print(file);
    }
    public static void print(File file){
        if(file.exists() && file.isDirectory()){
            File [] files = file.listFiles();
            if(files.length > 0 && files != null){
                for(int i = 0; i < files.length; i++){
                    print(files[i]);//递归调用
                }
            }
        }
        System.out.println(file);
    }
}

二、字节流和字符流:

  使用File类只能进行文件本身的操作,但是与内容的操作无关。如果想进行文件内容操作可以使用一下两组流:

  .字节流InputStream OutputStream

  .字符流reader writer

  不管使用哪种流,基本的操作流程是一样的,以文件操作为例:

  .确定操作文件的路径

  .通过字节流或字符流的子类为字节流和字符流类对象实例化

  .进行流入、流出操作

  .关闭流,流属于资源操作,资源操作完成一定要关闭

1、字节输入流:OutputStream

  java.io.OutputStream是可以进行字节数据(byte)的输出

  OutputStream类中存在三个write()方法:

    ·输出单个字节:public void write(int b);

    ·输出全部字节:public void write(byte [] b);

    ·输出部分字节:public void write(byte [] b,int off,int len);

  OutputStream是一个抽象类,所以可以使用子类对其进行实例化。对文件操作,可以使用FileOutputStream,这个类有两个常用的构造方法:

    public FileOutputStream(File file) throws FileNotFoundException,覆盖;

    public FileOutputStream(File file, boolean append) throws FileNotFoundException,追加;

对文件进行覆盖的输出操作:

package com.java.io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class TestFile {
    public static void main(String [] args) throws IOException{
        File file = new File("G:" + File.separator + "Test" + File.separator + "demo.txt");
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        //通过OutputStream的子类对象为父类对象实例化
        OutputStream output = new FileOutputStream(file);
        //要输出的数据
        String msg = "Hello world.";
        //将字符串转换为字节数组
        byte [] data = msg.getBytes();
        //输出字节数组
        output.write(data);
        output.flush();
        //关闭
        output.close();
    }
}

  不管执行几次,都是对当前文件的覆盖。如果不想覆盖,可以使用追加的方式创建FileOutputStream类对象

    .追加内容:OutputStream output = new FileOutputStream(file, true);

  单个字节:

package com.java.io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class TestFile {
    public static void main(String [] args) throws IOException{
        File file = new File("G:" + File.separator + "Test" + File.separator + "demo.txt");
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        //通过OutputStream的子类对象为父类对象实例化
        OutputStream output = new FileOutputStream(file,true);
        //要输出的数据
        String msg = "Hello world.\r\n";
        //将字符串转换为字节数组
        byte [] data = msg.getBytes();
        //输出字节数组
        for(int i = 0; i < data.length; i++){
            output.write(data[i]);
        }
        //关闭
        output.close();
    }
}

2、字节输入流:InputStream

  在InputStream类中定义有三个read()方法:

    ·读取单个字节:public int read() throws IOException;

      每次使用read()操作将读取一个字节数据,此时返回的是数据,如果数据已读完,则int返回-1

    .读取内容到字节数组:public int read(byte [] b) throws IOException();

      将内容读取到字节数组中,返回读取的个数,如果读取完毕,则返回-1

    .读取内容到部分字节数组:public int read(byte [] b,int off,int len) throws IOException();

      将指定长度的内容读取到字节数组中,返回读取个数,如果读取完毕,则返回-1

  InputStream是抽象类,所以可以使用它的子类对其进行实例化。使用FileInputStream子类完成,其构造方法:

    public FileInputStream(File file) throws FileNotFoundException;

  使用InputStream读取数据

package com.java.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class TestFileOne {
    public static void main(String[] args) throws Exception {
        File file = new File("G:"+File.separator+"Test"+File.separator+"demo.txt");
        if(file.exists()){//文件存在
            InputStream input = new FileInputStream(file);
            byte [] data = new byte[1024];//此数组用于接受全部输入数据
            int len = input.read(data);//将数据保存到数组中
            System.out.println(""+new String(data, 0, len));
            input.close();
        }
    }
}

  实际开发中使用while循环读取

package com.java.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class TestFileOne {
    public static void main(String[] args) throws Exception {
        File file = new File("G:"+File.separator+"Test"+File.separator+"demo.txt");
        if(file.exists()){//文件存在
            InputStream input = new FileInputStream(file);
            byte [] data = new byte[1024];//此数组用于接受全部输入数据
            int temp = 0;//定义每次读取进来的数据
            int foot = 0;//定义数组角标
            //(temp = input.read()) != -1 判断temp是否等于-1,如果不是则继续读
            while((temp = input.read()) != -1){
                data[foot++] = (byte) temp;
            }
            input.close();
            //打印
            System.out.println(new String(data, 0, foot));
        }
    }
}

 

以上是关于关于Java的File类字节流和字符流的主要内容,如果未能解决你的问题,请参考以下文章

Java IO 字节流与字符流

IO流

IO流

java的I/O介绍

[Java]I/O底层原理之一:字符流字节流及其源码分析

Java基础 -- IO流