百木园-与人分享,
就是让自己快乐。

java学习之IO流

java io流有四大家族分别是:
1.InputStream(字节输入流) 2.OutputStream(字节输入出流)3.Reader(字符输入流)4.Writer(字符输出流)四个类都是抽象类

0x01字节流的输入和输出

0x1FileInputStream

class FileInputStreamTest{
    public static void main(String[] args) {
        FileInputStream fis=null;
        try {
            fis =new FileInputStream(\"C:\\\\Users\\\\钟林\\\\untitled\\\\src\\\\com\\\\zhonglin\\\\www\\\\TEset\");//绝对路径
            while (true){
                int data=fis.read();//read会依次向下读没有字节的时候就会返回-1
                if (data==-1){
                    break;
                }System.out.println(data);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

提高效率使用byet和while循环数组去读取字节

class FileInputStream_test02{
    public static void main(String[] args) {
        FileInputStream fis=null;
        try {
            fis=new FileInputStream(\"C:\\\\Users\\\\钟林\\\\untitled\\\\src\\\\com\\\\zhonglin\\\\www\\\\TEset\");
            byte[] bytes=new byte[ 4];
            int flag=0;
            while ((flag=fis.read(bytes))!=-1){
                System.out.println(new String(bytes,0,flag));
    
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

available()方法用法:
1.可以获取文件还可以读取的字节数量
2.可以使用read(对象.available)一次性读取完整个文件夹,但是不适用与大文件,因为byte数组不能太大
skip()方法:
1.跳过几个字节不读取skip(int a)

class FileInputStream_test03{
    public static void main(String[] args) {
        FileInputStream fileInputStream=null;
        try {
            fileInputStream=new FileInputStream(\"C:\\\\Users\\\\钟林\\\\untitled\\\\src\\\\com\\\\zhonglin\\\\www\\\\TEset\");
            int flag=fileInputStream.read();
            System.out.println(\"剩下多少个字节key读\"+fileInputStream.available());//剩下多少个字节key读
            byte[] bytes=new byte[fileInputStream.available()];//可以这样一次读取完不用循环
            fileInputStream.read(bytes);
            //不适用与大文件byte数组不能太大
            System.out.println(new String(bytes));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

0x2FileOutputStream

writre()方法:
1.在构造方法的后面加一个true代表文件追加,在文件后面继续写入
fileOutputStream=new FileOutputStream(\"myfile\",true);
2.写入完成后一定要flush。
fileOutputStream.flush();
3.String对象转成byte数组类型

String str1=\"我是以中国人\";

 byte[] bytes1=str1.getBytes(StandardCharsets.UTF_8);
            fileOutputStream.write(bytes1,0,bytes1.length);`
            fileOutputStream.flush();

看一下代码

class FileOutputStream_test02{
    public static void main(String[] args) {
        FileOutputStream fileOutputStream=null;
        try {
            fileOutputStream=new FileOutputStream(\"myfile\",true);//在后面加一个ture代表追加写入
            byte[] bytes={88,66,52,99};
            fileOutputStream.write(bytes,0,2);//从0到2
            fileOutputStream.flush();//写完一定要刷新

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();

                }

            }
        }


    }
}
小结
------InputStream------
public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() : 从输入流读取数据的下一个字节。
public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
------OutputStream-----
public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。(写完一定要执行)
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输
出到此输出流。
public abstract void write(int b) :将指定的字节输出流。

0x02字符流的输入和输出

1.FileReader
a.大部分跟前面的差不多需要把原来的byte数组变成char数组
b.public void close() :关闭此流并释放与此流相关联的任何系统资源。
c.public int read() : 从输入流读取一个字符。
d.public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。

char[] chars=new char[4];
            int flag=0;
            while ((flag=fileReader.read())!=0);
            System.out.println(new String(chars,0,flag));

2.FileWriter
a.flush :刷新缓冲区,流对象可以继续使用。
b.close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
c.大部分共性相同

void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len
写的字符个数。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个
数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。

0x03缓冲流的输入和输出

1.使用这个流的时候不需要自定义char/byte数组,此流自带。
2.外部包装的流叫包装流(处理流),传入的流叫节点流。
3.字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader , BufferedWriter
4.看一下字节缓冲构造方法:

public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。

5.字符缓冲流:

public BufferedReader(Reader in) :创建一个 新的缓冲输入流。
public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。

需要参数Reader但是Reader是完全抽象的只能去寻找它的子类

    public static void main(String[] args) throws IOException {
public static void main(String[] args) throws IOException {
        BufferedReader bis = new BufferedReader(new FileReader(\"a.txt\"));
            String b = null ;
            while ((b = bis.readLine())!=null){//读取一行
                System.out.println(b);
            }
            bis.close();
    }

    }

0x04其他流的使用

0x1数据流

1.DataOutputStram和DataInputStream,数据流对应的读写只能对应这两个
2。write(数据类型)()会把对象的数据和类型一并传过去
3.可以通过read(数据类型)()等方法读取固定类型数据

class DataOutputStream_Test{
    private static DataInputStream ios;

    public static void main(String[] args) throws Exception {
        DataOutputStream dos=new DataOutputStream(new FileOutputStream(\"C:\\\\Users\\\\钟林\\\\untitled\\\\myfile\"));
        DataInputStream ios=new DataInputStream(new FileInputStream(\"C:\\\\Users\\\\钟林\\\\untitled\\\\myfile\"));
        byte b=100;
        int  a=100;
        dos.writeByte(a);//会把数据和类型一起传过去
        dos.writeByte(b);
        ios.readByte();
        dos.flush();
        dos.close();
    }
}

0x05File类

1.File类不属于io流,不能完成文件数据的读写。
2.File对象带包的是:文件目录路径名抽象的表示形式。
3.常用方法
public String getAbsolutePath() :返回此File的绝对路径名字符串。
public String getPath() :将此File转换为路径名字符串。
public String getName() :返回由此File表示的文件或目录的名称。
public long length() :返回由此File表示的文件的长度。
public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isFile() :此File表示的是否为文件。
public boolean createNewFile() :当前仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete() :删除由此File表示的文件或目录。
public boolean mkdir() :创建由此File表示的目录。//这个可以创建父目录
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。
public long lastModified():返回最后一次修改时间
4.看一下简单的代码

public class File_Test {
    public static void main(String[] args) throws Exception {
        File file=new File(\"C:\\\\Users\\\\钟林\\\\untitled\\\\myfile\");
        System.out.println(file.exists());//判断是否存在。返回一个boolen值
        if (file.exists()){
            file.createNewFile();//文件的方式新建
            file.mkdir();//以目录的方式存在
            file.getName();//获取名字
            file.isFile();
            file.isDirectory();
            long haomiao=file.lastModified();//最后一次修改时间.从1970年到现在的毫秒数
            Date time=new Date(haomiao);//这样就可以转化成日期
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss SSS\");
            String stdtiemSTR= simpleDateFormat.format(time);
            System.out.println(stdtiemSTR);

        }
    }
}

0x06序列化和反序列化

1.java提供了一种对象序列化的机制,用一个字节序列表示一个对象,该字节包含对象的数据、对象的类型、对象的存储属性。字节序列写出到文件后,相当于可以持久报错了一个对象信息,这过程叫做序列化
而反过来,将存储在文件的字节序列从文件中读取出来,重构对象,重新用来创建对象,这步骤叫做反序列化。
2.public ObjectOutputStream(OutputStream out): 创建一个指定InputStream的ObjectOutputStream。
3.public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream。
4.要实现序列化必须要去实现一个接口Serializable,implements Serializable,它只是一个标志接口里面没有存在任何

看一下代码(序列化)

class ObjectOutputStream_Test implements Serializable{

    @Override
    public String toString() {
        return super.toString();
    }

    int id;
    private String name;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;

    }
    public ObjectOutputStream_Test(int id,String name){
        this.id=id;
        this.name=name;
        }



    public static void main(String[] args) throws Exception {
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(\"XULIEHUAt\"));
        ObjectOutputStream_Test obj=new ObjectOutputStream_Test(10,\"zl\");
        objectOutputStream.writeObject(obj);
        objectOutputStream.flush();
        objectOutputStream.close();
    }
}

看一下反序列化

readObject()方法反序列化回来

 public static void main(String[] args) {
        Method e = null;
        try {
            FileInputStream fis = new FileInputStream(\"a.txt\");
            ObjectInputStream ois = new ObjectInputStream(fis);
             e = (Method) ois.readObject();
            ois.close();
            fis.close();
        } catch (IOException | ClassNotFoundException ioException) {
            ioException.printStackTrace();
        }
        System.out.println(\"name=\"+e.name);
        System.out.println(\"address =\"+e.address);
        System.out.println(\"age=\"+e.age);
    }

反序列化失败——InvalidClassException

当你序列化class后class里面的代码发生了改变,源码改动以后需要重新编译,编译以后变成了全新的字节码文件。
并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生改变
Serializable 接口给需要序列化的类,提供了一个序列版本号。 serialVersionUID 该版本号的目的在于验证序
列化的对象和对应类是否版本匹配。
我们可以给它一个固定不变的序列号private static final long serialVersionUID = 1L;
代码

public class Employee implements java.io.Serializable {
// 加入序列版本号
private static final long serialVersionUID = 1L;
public String name;
public String address;
// 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.
public int eid;
}
}

0x07总结

1.FileoutputStream/FileInputStream:字节的方式输入和输出
2.FileReade/FileWriter:字节的方式输入输出
3.字节缓冲流: BufferedInputStream , BufferedOutputStream
4.字符缓冲流: BufferedReader , BufferedWriter
io流主要应用在各种脚本的开发列如,一个目录爬行要去使用字典文件,还可以用来进行文件加密。后面可以深入研究一下序列化漏洞


来源:https://www.cnblogs.com/0x3e-time/p/16141290.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » java学习之IO流

相关推荐

  • 暂无文章