Java学习笔记(六):File、字节流、字符流

 

写在前面:

File
createNewFile()     mkdir()     mkdirs()
delete()

exists()     isDirectory()     isFile()

getName()     getPath()     getAbsolutePath()

list()    listFile()

字节流

抽象类

InputStream

OutputStream

文件:

FileInputStream (path/File)  

FileOutputStream (path/File, [true 追加])

fis.read(空/ byte[])  byte[]返回byte长度

fos.write(int/ byte[]/ byte[], int,int)  

缓冲:

BufferedInutStream(InputStream)

BufferedOutputStream(OutputStream)

同上

对象序列化:

ObjectOutputStream(OutputStream)

对象反序列化:

ObjectInputStream(InputStream)

oos.writeObject(Object)

ois.readObject()

 

相应的类:

实现接口 Serializable

定义静态常量 SerialVersionUID

不序列化的对象需要用 transient 修饰

打印类

PrintStream (path)

 

转码:

ps.write(int/ byte[]/ byte[], int,int)  //同OutputStream

不转码:

ps.print(xxx)

ps.println(xxx)

字符流

抽象类

Reader

Writer

InputStreamReader (Inputstream, [String 编码])

OutputStreamWriter (OutputStream, [Stirng 编码])

isr.read (空/ char[])

 

osw.write (int /char[]/ String /

char[],int,int/ String,int,int)

 

osw.flush()

上面的简化:默认编码

FileReader (path)

FileWriter (patn)

同上

缓冲:

BufferedReader (Reader)

BufferedWriter (Writer)

同上

 

另:特有方法

br.readLine()

bw.newLine()

打印类

PrintWriter(path /

Writer,boolean)

boolean为true: 自动刷新

 

使用同打印字节流

 

另:没有自动刷新时 添加刷新方法

pw.flush()

 

Properties

针对Object类型,使用同map

prop.put (k,v)

prop.get (k)

prop.keySet()

针对 String 类型,特有方法

prop.setProperty (k,v)

prop.getProperty (k)

prop.StringPropertyNames()

与 IO 结合

文件内容 写入 Properties:

prop.load (InputStream/ Reader)

Properties内容 写入 文件:

prop.store (OutputStream/ Writer, String 说明)

 

 



1. File

File:文件和路径名的抽象表示,仅仅是一个路径而已

File重写了toString()方法,返回路径名

//三种构造方法:只是一个路径名,并没有做创建等操作
        File file01=new File("/Users/rainbow/Desktop/test01.txt");

        File file02=new File("/Users/rainbow/Desktop","test02.txt");

        File file031=new File("/Users/rainbow/Desktop");
        File file03=new File(file031,"test03.txt");
创建文件的方法
createNewFile()创建文件;文件不存在返回true,存在返回false
mkdir()创建目录
mkdirs()创建多级目录
        File file01=new File("/Users/rainbow/Desktop/test01/test02");
        File file02=new File("/Users/rainbow/Desktop/test01/test02/test.txt");
        file01.mkdirs();
        try {
            file02.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
删除(文件、目录)
delete()删除文件或目录;目录下有内容时,不能直接删除
判断、获取

exists()

isDirectory()

isFile()

是否存在

是不是目录

是不是文件

getName()

getPath()

getAbsolutePath()

文件名

路径名

绝对路径名

list()

listFile()

目录下的文件和目录 String[]格式

目录下的文件和目录 File[]格式

2. 字节流

流:数据传输

IO流:设备间的数据传输

输入流/输出流:读数据--输入流,写数据--输出流

字节流/字符流:txt不能读懂的--字节流(万能的),txt能读懂的--字符流

  • 抽象类:InputStream、OutputStream

InputStream:字节输入流的超类,子类以InputStream作后缀

OutputStream:字节输出流的超类,子类以OutputStream作后缀

  • 文件输出流:FileOutputStream(向文件写数据)

简单流程:

//1. 创建文件;创建字节流对象;字节流对象指向文件
FileOutputStream fos=new FileOutputStream("test01.txt");
//2. 写文件:写的是字节,文件中显示a
fos.write(97);
//3. 所有IO相关的操作都要释放资源并关闭流
fos.close();

追加写入:

new FileOutputStream(path, true);    //path处可以是String,也可以是File

写文件:

write(int b);    //写一个字节

write(byte[] b);    //多个字节:定义byte[],或者string.getBytes()

write(byte[] b, int off, int len);    //多个字节,从字节的索引off开始写len个字节

写回车:

linux   \n

mac   \r

window   \r\n

  • 文件输入流:FileInputStream(从文件读数据)

简单流程:

//1. 创建文件;创建字节流对象;字节流对象指向文件
FileInputStream fis=new FileInputStream("test01.txt");
//2. 读文件:返回int,返回值 -1 结束
fis.read();
//3. 所有IO相关的操作都要释放资源并关闭流
fis.close();

读文件:

read();    //一个字节

read(byte[]);    //读一个字节数组,返回实际读到的个数 (注意:会读到换行符)

一般定义的数组大小为1024及其整数倍:byte[] b=new byte[1024];

 

//例子:复制图片
    public void fileCopy(){

        FileInputStream fis=null;
        FileOutputStream fos=null;
        try {
            fis=new FileInputStream("/Users/rainbow/Pictures/1.jpg");
            fos=new FileOutputStream("copy.jpg");

            byte[] bytes=new byte[1024];
            int len;
            while ((len=fis.read(bytes)) != -1){
                fos.write(bytes,0,len);    //读多长,就写多长
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {        //close
            if(fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
//(JDK7之后的改进)异常处理的改进

    public void fileCopy(){
        try (FileInputStream fis=new FileInputStream("/Users/rainbow/Pictures/1.jpg");
             FileOutputStream fos=new FileOutputStream("copy.jpg");) {

            byte[] bytes=new byte[1024];
            int len;
            while ((len=fis.read(bytes)) != -1){
                fos.write(bytes,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 
        //自动释放资源

    }
  • 字节缓冲流:BufferedInputStream、BufferedOutputStream

只提供缓冲区,读写数据还是要靠基本的字节流对象

内置缓冲区数组,数组大小默认8192

BufferedOutputStream:向 底层输出流 写入字节,不用每个字节都调用底层系统

简单流程:

BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("test.txt"));
bos.write("abc".getBytes());
bos.close();
//例子:复制视频

    public void videoCpoy(){

        try (BufferedInputStream bis=new BufferedInputStream(new FileInputStream("/Users/rainbow/Desktop/小猫.mp4"));
            BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("copyVideo.mp4"));) {
            
            byte[] bytes=new byte[1024];
            int len;
            while((len=bis.read(bytes)) != -1){
                bos.write(bytes,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

3. 字符流:字节流+编码表

汉字:汉字存储,第一个字节一定是负数

BGK编码:2个字节

UTF-8编码:3个字节

字节流操作汉字不方便,所以提供字符流

编码和解码要用同一个编码表(比如都用UTF-8)

//例子
    public void code(){
        String str="中国";
        byte[] bytes= new byte[0];
        try {
            //编码
            bytes = str.getBytes("UTF-8");
            for (byte by:bytes) {
                System.out.println(by);
            }
            //解码
            String string=new String(bytes,"UTF-8");
            System.out.println(string);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
  • 抽象类:Writer、Reader
  • Writer:字符输出流的超类,子类以Writer作后缀

    Reader:字符输入流的超类,子类以Reader作后缀

  • OutputStreamWriter、InputStreamReader

可以采用系统默认编码,也可以指定编码

简单流程:(写文件)

FileOutputStream fos=new FileOutputStream("/Users/rainbow/Desktop/test01.txt");
OutputStreamWriter ost=new OutputStreamWriter(fos, "UTF-8");
ost.write("你好");
ost.flush();
ost.close();

new OutputStreamWriter(OutputStream子类对象, 编码格式);  //编码格式不写,表示采用系统默认编码格式

flush方法://刷新流

字符流写数据,不能直接写入文件,会先写入缓冲区

调用flush方法,将缓冲区中内容写入文件

flush方法后可继续写文件

close方法:

close方法,释放资源并关闭流

在关闭流之前会先刷新(flush),所以调用close方法时,可以不调用flush方法

read() 参数:

空:一次一个字节,返回读到的信息

char[ ]:一次一个字符数组,返回实际读到的数组长度

write() 参数:

int:一次一个字符

char[ ]:一次一个字符数组

char[]  c,int  off,int  len:从数组的off索引开始,取长度len

String:字符串

String,int  off,int  len:字符串从索引off开始,读取len长度

  • FileReader、FileWriter:简化

采用默认编码方式

构造方法可以直接写路径:FileReader(String path)

使用方法同:InputStreamReader、OutputStreamWriter

  • BufferedReader、BufferedWriter:字符缓冲流

缓冲区默认数组大小8192

简单流程:

BufferedReader br=new BufferedReader(new FileReader("/Users/rainbow/Desktop/test01.txt"));
br.readLine();
br.close();

字符缓冲流特有方法:

readLine() :读取一行数据,不包括换行符;读到 null 表示结束

newLine() : 写换行

    public void zifu(){
        String path="/Users/rainbow/Desktop/test01.txt";
        //简单字符流写文件
        try(
        FileOutputStream fos=new FileOutputStream(path);
        OutputStreamWriter ost=new OutputStreamWriter(fos, "UTF-8");
        ){
            ost.write("你好");
            ost.write("\r"); //mac
            ost.write("Java");
            ost.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
        
        //字符缓冲流读取文件
        try(
        BufferedReader br=new BufferedReader(new FileReader(path));
        ){
            String str;
            while((str=br.readLine()) != null) {
                System.out.println(str);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

4. 打印

  • PrintStream:打印字节

new PrintStream(path)  :使用文件名,创建打印流

write :打印会转码

print / println : 原样输出

        String path="/Users/rainbow/Desktop/test01.txt";
        //字节
        try(
        PrintStream ps=new PrintStream(path);
        ){
            ps.write(97);//打印:a
            ps.print(97); //打印:97
            ps.println(97); //打印:97
        }catch (IOException e){
            e.printStackTrace();
        }
  • PrintWriter:打印字符

因为是打印字符,所以需要刷新

两种构造方法:new PrintWriter(path);    

                           new PrintWriter(Writer, boolean); //boolean为true,表示自动刷新,不用再写flush方法

        //字符
        try(
        PrintWriter pw=new PrintWriter(path);
        ){
            pw.write("你好");
            pw.flush();
        }catch (IOException e){
            e.printStackTrace();
        }

        //字符
        try(
        PrintWriter pw=new PrintWriter(new FileWriter(path),true);//true自动刷新
        ){
            pw.println("你好啊");
        }catch (IOException e){
            e.printStackTrace();
        }

5. 字节流---对象序列化

将对象保存到磁盘,或在网络中传输,需要使用 字节序列 表示对象(对象序列化)

类需要实现接口:Serializable,只是一个标识接口,没有方法需要重写

                               为每个类关联一个版本号UID,类修改后,UID发生变化

                               可在类内显示定义一个UID,以保证类修改后,UID不变:serialVersionUID

private static final long serialVersionUID=1L;//数值自己定

                               类内不想被序列化的成员变量(不想让别人知道的成员):用 transient 修饰

private transient int age;
  • ObjectOutputStream:序列化流
  • ObjectInputStream:反序列化流

new ObjectOutputStream(OutputStream) 、 new ObjectInputStream(InputStream)

序列化方法:oos.writeObject(Object obj);

反序列化方法:Object o = ois.readObject();

    public void funSerial(){
        String path="test01.txt";
        Student student=new Student(1,"xiaohei",23);
        
        //序列化
        try (
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(path));
        ){
            oos.writeObject(student);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        //反序列化
        try (
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(path));
        ){
            Object o = ois.readObject();
            System.out.println(o);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

6. 附加:Properties

properties:map体系的集合类,可保存到流中,也可从流中加载

  • Properties

key和value的类型都是Object,使用同map

有针对String类型的特有方法:

        Properties properties=new Properties();
        properties.setProperty("A","apple"); // 同Object类型的:properties.put("A","apple");
        properties.getProperty("A"); // 同Object类型的:properties.get("A");
        properties.stringPropertyNames();// 同Object类型的:properties.keySet();
  • Properties 与 IO 结合

将文件内容写入Properties:load

properties.load(InputStream); //字节

properties.load(Reader); //字符

将Properties内容写入文件:store

properties.store(OutputStream,String comments); //字节;comments说明,没有特殊说明就写 null

properties.store(Writer,String comments); //字符

    public void funProperties(){
        String path="test01.txt";

        Properties properties=new Properties();

        //方法测试
        properties.setProperty("A","apple"); // 同Object类型的:properties.put("A","apple");
        properties.getProperty("A"); // 同Object类型的:properties.get("A");
        properties.stringPropertyNames();// 同Object类型的:properties.keySet();

        //与 IO 结合
        try (
                FileWriter fw=new FileWriter(path);
                FileReader fr=new FileReader(path);
        ){
            //properties内容写入文件
            properties.store(fw,null);
            //文件内容写入properties
            properties.load(fr);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值