javaSE高级开发之文件I/O(上)

文件通常是程序中数据的初始源和目的地,因此对文件的输入输出流操作是普遍存在的.

文件类:File类

java.io.File是一个普通类,直接产生实例化对象即可,其构造方法有:

public File(String pathName);
public File(String parentPathName,String childPathName);

文件路径分割符在Unix或Ninux系统下是:/ Windows系统下是:
因此,为保证程序的跨平台使用,用File的静态方法File.separator代替分割符
名称分隔符Unix或Ninux系统下是冒号":" Windows系统下是分好";"因此,为保证程序的跨平台使用,用File的静态方法File.pathSeparator代替名称分割符

File类的方法使用

1.创建一个新文件

public boolean createNewFile();
public class UseFile {
    public static void main(String[] args) {
        File file=new File("D:"+File.separator+
                "TL-BITE"+File.separator+"Test");
        try {
            //新建一个文件
            file.createNewFile();
            System.out.println("创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.判断文件是否存在

public  boolean exists();

3.删除文件

public boolean delete();
//通过路径类Paths的静态方法get,将路径或url转为Paths类对象
//再通过调用paths的接口类Path的方法toFile,将Paths的对象(路径)转为文件类对象
        File file =Paths.get("D:","TL-BITE","Test").toFile();
        if(file.exists()){
            file.delete();
            System.out.println("删除成功");
        }else{
            System.out.println("文件不存在");
        }
    }

4.取得父路径或父File对象

public String getParent();
public File getParentFile();
File file = Paths.get("D:", "TL-BITE", "Test","test.txt").toFile();
		 String path1=file.getParent();
        System.out.println(path1);//  D:\TL-BITE\Test
        File f1=file.getParentFile();
        System.out.println(f1);//   D:\TL-BITE\Test

5.无论有多少级目录,都会创建目录

public boolean mkdirs();

6.只创建当前目录

public boolean mkdir();
      File file=new File("D:\\TL-BITE\\Test\\mkdir");
        //D:\TL-BITE\Test存在,只用创建当前一层目录mkdir
        if(file.mkdir()){
            System.out.println("D:\\TL-BITE\\Test\\mkdir创建成功");//ok
        }else{
            System.out.println("创建失败");
        }
        File file1=new File("D:\\TL-BITE\\Test\\test1\\mkiirs");
        //D:\TL-BITE\Test存在,需创建多层目录
        if(file1.mkdirs()){
            System.out.println("D:\\TL-BITE\\Test\\test1\\mkiirs创建成功");//ok
        }else{
            System.out.println("D:\\TL-BITE\\Test\\test1\\mkiirs创建失败");
        }
    }

7.输出目录所有文件

public String[] list();
public File[] listFile();
File file = Paths.get("D:","TL-BITE","Test").toFile();
        File[] files=file.listFiles();
        for(File f : files){
            System.out.println(f);
        }

8.取得文件属性

public boolean isFile();//判断路径是否文件
public boolean isDirectory()//判断路径是否目录
public long length()//取得文件大小(字节)

public long lastModified()//最后一次修改日期
//从1970年1月一日00:00:01直至上一次修改经历的秒数
 File file =new File("D:\\TL-BITE\\Test");
        if(file.exists()){
            System.out.println(file.getName());//获取文件名
            System.out.println(file.getPath());//获取文件路径
            System.out.println(file.length());//获取文件大小
            System.out.println(file.lastModified());//获取文件上一次修改时间

            //利用文件上一次修改时间作为Date类对象,输出年月日格式时间
            System.out.println(new Date(file.lastModified()));
        }

输出结果:
在这里插入图片描述

字节流

1.数据流的概念和划分

流的概念类似于管道,通过管道来实现程序或进程之间的通信.
输入流:将数据源传递给程序.
输出流:从程序传递到目标(内存,文件,网络等).
不管是字节流还是字符流,其基本操作基本相同,本质区别是:字节流是原生操作,而字符流是经过处理后的操作.
根据组成流的不同,将流分为字节流和字符流.字节流是由字节(1字节=8bit)组成,主要用于处理二进制数据;InputStream是所有字节输入流的父类.

字符流是由字符(1字符=2字节=16bit)组成,主要用于处理文本数据.OutputStream是所有字节输出流的父类.

字节流在javaI/O系统中提供了InputStream和OutputSTream两个抽象类,分别实现字节的输入输出.

继承自InputStream字节输入流的子类有:ByteArrayInputStream FileInoutStream FileterInputStream StringBufferInputStream等

继承自OutputStream的子类有:ByteArrayOutputStream FileOutoutStream FileterOutputStream StringBufferOutputStream

2.FileInputStream类

1.构造方法

public FileInputStream(File file);

2.读取文本内容

public void read(byte[] b);

3.关闭数据流

public void close();
	 //1.准备文件:声明File类
        File file=new File("D:\\TL-BITE\\Test\\test.txt");
        //2.声明InputStream 对象
        InputStream ins=null;
        //根据文件内容的大小,确定数组的长度
        //file.length()返回值为long,需强转
        byte[] b=new byte[(int)file.length()];
        int temp=0;
        int len=0;
        try {
        //3.实例化InputStream 对象
            ins=new FileInputStream(file);
            while(((temp=ins.read())!=-1)){
                //按字节读取,将读到的每个字节分别存入数组
                b[len]=(byte)temp;
                len++;
            }
            ins.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(new String(b));

3.FileOutputStream类

1.构造方法

    public FileOutputStream(File file );(覆盖)
    public FileOutputStream(File file ,boolean append);(追加)

输出流文件若不存在,系统自动创建,若目录不存在,则不能创建

2.将给定字节数组内容全部输出

public void write(byte[] b);

3.将给定字节数组内容部分输出

public void write(byte[] b,int off,int len);

4.关闭数据流

public void close();
 File file =new File("D:\\TL-BITE\\Test\\test.txt");
        if(!file.getParentFile().exists()){
          //若目录不存在,输出流不能自动创建文件
           file.getParentFile().mkdirs();
        }
        OutputStream out=null;
        try {
            out=new FileOutputStream(file);
            String msg="我正在学习";
            //将字符串转为字节数组写入文件,并且是覆盖性写入
            out.write(msg.getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

AutoCloseable自动关闭支持

从JDK1.7开始支持AutoCloseable接口,为实现自动关闭,结合

try(){
}catch(){
}

结构使用.将输入输出流对象声明与初始化模块写在try后面的圆括号中.

  @Override
    public void close() throws Exception {
        System.out.println("已经自动关闭");
    }
    public static void testClose(){

    try(UseFileOutputStream uo=new UseFileOutputStream();){
        System.out.println("我已经学习很久了");
    } catch (Exception e) {
        e.printStackTrace();
    }
    }

输出结果:
在这里插入图片描述

字符流

1.字符输出流

字符流是由字符(1字符=2字节=16bit)组成,主要用于处理文本数据.,这个类实现了Closeable接口,因此可以自动关闭流(配合try-with-resources).还实现了Appendable,Flushable接口.

Writer类与OutputStream类在功能上时一致的,Write数据的单位是字符,OutputStream的数据单位是字节.Writer本身也是一个抽象类,不能实例化.
常用方法:
1.直接写入

public void write(char[] cbuf)//写入一个字符数组。  
public abstract void write(char[] cbuf, int off, int len)//写入字符数组的一部分。  
public void write(int c)//写一个字符  
public void write(String str)//写一个字符串  
public void write(String str, int off, int len)//写一个字符串的一部分。  

2.将指定字符添加到输出流中

public  Writer append(char c)

3.刷新缓冲区中的数据

public abstract void flush()

2.FileWriter类

继承自Writer类
构造方法:

public FileWriter(File file)
public FileWriter(File file,boolean append)

向文件写入内容范例:

File file = new File("D:\\TL-BITE\\Test\\write\\write1.txt");
        //若当前文件不存在,new File可自动创建文件,
        // 若上层目录都不存在,则创建失败,需创建目录
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        String msg = "我正在学习字符流";
        try (Writer out = new FileWriter(file);) {
            out.write(msg.toCharArray(), 0, 3);
             out.append("神书仙侠倚奇缘");
            System.out.println("写入成功");
        } catch (IOException e) {
            System.out.println("写入失败");
            e.printStackTrace();
        }

 File file = new File("D:\\TL-BITE\\Test\\write.txt");
        //利用try-with-resources实现自动关闭流
        try (Writer out = new FileWriter(file)) {
            String msg = "神书仙侠倚奇缘";
            //write方法写入支持 字符串\数组\整数
            out.write(msg,2,4);
        } catch (IOException e) {
            e.getMessage();
        }

3.FileReader

进行文件读取,继承自Reader类
构造方法

FileReader(File file)//创建一个新的 FileReader ,给出 File读取。  
FileReader(FileDescriptor fd)//创建一个新的 FileReader ,给定 FileDescriptor读取。  
FileReader(String fileName)//创建一个新的 FileReader ,给定要读取的文件的名称。  

常用方法:
1.读字符

public int read() //读一个字符  
public int read(char[] cbuf) //将字符读入数组。  
public abstract int read(char[] cbuf, int off, int len) //将字符读入数组的一部分。  
public int read(CharBuffer target) //尝试将字符读入指定的字符缓冲区。 

读取内容范例:

   File file = Paths.get("D:", "TL-BITE", "Test", "write.txt").toFile();
        if(file.exists()){
        //记录读文开始的时间,单位为毫秒
            long start=System.currentTimeMillis();
            try(Reader in=new FileReader(file)){
                char[] date=new char[3];
                int len=-1;

                while((len=in.read(date))!=-1){
                    for(char i: date){
                        System.out.println(i);
                    }
                }
                //记录读文件结束的时间
                long end=System.currentTimeMillis();
                
                System.out.println("读取成功,花费了"+(end-start));
            }  catch (IOException e){
                System.out.println("读取失败");
                e.printStackTrace();

            }
     

//将读到的内容写入新文件

 File srcFile=new File("D:\\TL-BITE\\Test\\write1.txt");
 File desFile=new File("D:\\TL-BITE\\Test\\writeread1.txt");
        try (Writer writer=new FileWriter(desFile);
        Reader reader=new FileReader(srcFile)){
            char[] buff=new char[3];
            int len=-1;
            
            //len --> 真正读取的内容长度
            while ((len=reader.read(buff))!=-1){
                writer.write(buff,0,len);
                // writer.write(buff);
                // 不添加写入方法的两个参数,就会将每次都读到的三个字符数组写入,最终写入结果会有出入
            }
        }catch (IOException e ){
            e.printStackTrace();
        }
       

字节流适合处理中文,字节流适合处理除中文外的一切数据类型

字节流与字符流的区别

实际开发中优先考虑字节流,只有处理中文时才会考虑字符流,因为字符流需要通过内存缓冲进行处理,如果字符流不关闭,数据就有可能保存在缓冲区没有输出到目标源,这种情况必须强制刷新才能够得到完整数据.

缓冲区:

当计算机访问外部设备或文件,要比直接访问内存慢得多,CPU要花费很多时间等待外部设备响应,因此,我们开辟一个内存缓冲区的内存区域,程序每次调用read()或write()方法,都是读写在这个缓冲区,当缓冲区被装满后,系统才将这个缓冲区内容一次集中写到外部设备或读取进来给cpu.使用缓冲区能有效的提高cpu的使用率,能提高整个计算机系统的效率.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值