zoukankan      html  css  js  c++  java
  • IO流知识点总结——博客园:师妹开讲啦

    课本知识点总结--博客园:师妹开讲啦

    Java中的流是有序的数据序列,是传递数据信息的载体,也是程序中的数据所经历的路径

    流根据方向可分为输入流和输出流:输入流是将数据源传递给程序,输出流是将数据从程序传递到目的地,如内存、文件、网络等。

    根据流的角色可分为节点流(FileInputStream、FileOutputStream、FileReader、FileWriter)和处理流

    根据组成流的不同,可以将其分为字节流(FileInputStream、FileOutputStream、BufferedInoutStream、BufferedOutputStream、ObjectInputStream、ObjectOutputStream)和字符流(FileReader、FileWriter、BufferedReader、BufferedWriter、InputStreamReader、OutputStreamWriter):字节流是由字节组成的,主要用于处理二进制数据(图片、音频文件),字符流是由字符组成,主要用于处理文本的数据。

    java.io.File类不属于Java流系统,但它是文件流进行文件操作的辅助类。

    File类的对象是一个“文件或目录”的抽象代表。File类的对象并不打开文件或目录,而是指定要操作的文件或目录。File类的对象一旦创建,就不能再更改,即它代表的抽象路径是不能改变的。

    String list[]=file.list();//只返回文件名,没有路径信息

    File listFile[]=file.listFiles();//不但返回文件名称还含有路径信息

    mkdir()——返回值类型:boolean,只能创建单层目录,不能含有子目录,即只能在已存在的目录中创建目录

    mkdirs()——返回值类型:boolean,可以创建多级目录,可以含有子目录,即可以在不存在的目录中创建文件夹

    例1:给定一个目录,列出此目录下的所有文件和目录

    public class ListFile{

      public static void main(String[] args){

        System.out.println("请输入路径:");

        Scanner scan=new Scanner(System.in);

        String path=scan.next();

        File file=new File(path);

        fileList(file);

        public static void fileList(File file){

          if(file.isFile()){

            System.out.println(file.getName());

          }else{

            System.out.println(" "+file.getPath()+"是目录");

            File fileName[]=file.listFiles();

            for(int i=0;i<fileName.length;i++){

              fileList(fileName[i]);

          }

        }

      }

    }

    向文件中写入时,若指定文件在操作前不存在,则操作之后系统会自动创建该文件,但目标文件存在的目录必须存在,否则抛出FileNotFoundException异常

    String s="Java学习手记";

    byte[] b=s.getBytes();

    char[] c=s.toCharArray();

    字节流是对文件本身直接进行操作,不需要通过缓冲区,而字符流则要通过缓冲流来操作文件,即使用字节流时,就算没有执行close()方法关闭字节流的操作,还是可以向文件输出内容的,但在字符流中,若不执行close()方法,就无法像文件写入内容,因为程序在执行过程中引入了缓冲区机制,即写操作先将内容放入缓冲区,若写操作完毕后,不将缓冲区内容刷新到文件,文件将为空,但可以使用flush()强制清除内容。执行close()方法时默认执行flush()方法

    转换流:BufferedRead——readLine()一次读取一行,BufferedWriter——newLine()写入一个行分隔符

    内存操作流:ByteArrayInputStream、ByteArrayOutputStream

    ByteArrayInputStream将数据写入内存中,ByteArrayInputStream类的实例化对象和执行read()方法都不需要处理异常,但调用close()方法需要处理异常,可调用的close()是没有任何操作的一个空方法,在关闭字节数组输入流后仍可被调用,而不会产生任何IOException

    内存操作流一般用于处理临时信息,因为临时信息不需要保存,使用后就可以删除

    PrintStream类是FilterOutputStream的子类

    例2:使用Scanner从文件中获取数据

    public class ScannerDemo{

      public static void main(String[] args){

        File file=new File("E:/JavaDemo/10/poetry.txt");

        if(!(file.exists())){

          System.out.println("文件不存在");

          System.exit(0);

        }

        FileInputStream fis=null;

        Scanner scan=null;

        try{

          fis=new FileInputStream(file);

          scan=new Scanner(fis);

        }catch(Exception e){

          e.printStackTreace();

        }

        StringBuffer sbu=new StringBuffer();

        while(scan.hasNext()){

          sbu.append(scan.next()).append(" ");

        }

        System.out.print(sbu);

      }

    }

    随机(任意)访问文件类:RandomAccessFile

    java.io.RandomAccessFile类不属于流,是Object的子类,但融合了流类InputStream和OutputStream的功能,既提供与InputStream类似的read()方法,又提供OutputStream类似的write()方法,还提供更高级的直接读写各种基本数据类型数据的读写方法,例如readInt()、writeInt(),该类还可以从文件的任意位置开始访问文件,但要求文件中的各个数据保存的长度必须相等

    顺序输入流(合并流):SequenceInputStream

    SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,在关闭输入流时,可只关闭顺序输入流,因为顺序输入流的close()方法将依次关闭被串联的输入流,但不会关闭输出流

    ZipEntry类的对象是用来表示ZIP文件条目,代表ZIP文件内的进入点(entry)

    例3:ZipOutputStream类压缩文件夹

    public class ZipOutputStreamDemo{

      public static void main(String[] args){

        File f1=new File("zip"); 

        File f2=new File("zipjava.zip");

        FileInputStream fis=null;

        FileOutputStream fout=null;

        ZipOutputStream zout=null;

        File fileName[]=null;

        byte b[]=new byte[1024];

        int temp=0;

        try{

          fout=new FileOutputStream(f2);

          zout=new ZipOutputStream(fout);

          zout.setComment("Use ZipOutputStream compression zip Directory");//设置注释

          if(f1.isDirectory()){

            fileName=f1.listFiles();

            for(int i=0;i<fileName.length;i++){

              fis=new FileInputStream(fileName[i]);

              zout.putNextEntry(new ZipEntry(fileName[i].toString()));

              System.out.println("正在压缩"+fileName[i]+".......");

              while((temp=fis.read(b))!=-1){

                zout.write(b,0,temp);

              }

              System.out.println("压缩"+fileName[i]+"完成");

            }

          }

          zout.close();

          fout.close();

          fis.close();

        }catch(Exception e){

          e.printStackTrace();

        }

      }

    }

    例4:ZipFile类解压缩ZIP文件

    public class ZipFileDemo{

      public static void main(String[] args){

        File file=new File("zipjava.txt");

        File zipFile=new File("java.zip");

        InputStream in=null;

        FileOutputStream fout=null;

        ZipEntry entry=null;

        ZipFile zip=null;

        byte b[]=new byte[1024];

        int temp=0;

        try{

          zip=new ZipFile(zipFile);

          entry=new ZipEntry("java.txt");

          in=zip.getInputStream(entry);

          fout=new FileOutputStream(file);

          while((temp=in.read(b))!=-1){

            fout.write(b,0,temp);

          }

          zip.close();

          fout.close();

        } catch(Exception e){

          e.printStackTrace();

        }

      }

    }

    博客园:师妹开讲啦

    对象序列化

    序列化:对象存储,对象转换为字节    反序列化:字节转换为对象

    对象的序列化的用途:1、把对象的字节序列永久的保存到硬盘上,通常存放在一个文件中 2、在网络上传送对象的字节序列

    如需要某个对象能支持序列化机制,必须让它实现Serializable接口,该接口只是一个标记接口,实现该接口无需实现任何方法,仅仅表明该类的对象是可序列化的

    对象被序列化时参与序列化的内容:属性、类名,不能序列化的内容:方法、类中的所有方法、static关键字和transient关键字修饰的属性

    Serializable接口和Externalizable接口均可以完成对象的序列化和反序列化,被Serializable接口声明的类对象的内容都将被序列化,而Externalizable接口声明的类的对象可以选择需要序列化的内容。但一般使用Serializable接口实现序列化,因为该接口不需要实现任何方法,而Externalizable接口定义了readExternal()和writeExternal()方法,实现该接口的类必须实现这两个方法

     视频知识点总结

    创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件,而且该文件回被创建到指定目录下,如果该目录下已有同名文件,将被覆盖。

    字节流如若不使用close()方法,结果仍可在文件中显示,字符流如若不使用close()方法则为空,可以使用flush()将缓冲去中缓存的内容推出,就可显示出内容。

    FileWriter fw=new FileWriter(“demo.txt”,true);//传递一个true参数,代表不覆盖已有的文件,并在已有文件的末尾处进行数据续写。

    记事本当中不能识别 ”,要想换行使用“

    只要用到缓冲区,就要刷新(flush()

    关闭缓冲区,就是在关闭缓冲区中的流对象

    缓冲区中提供了一个跨平台的换行符(newLine()

    缓冲区提供了一个一次读一行的方法readLine(),方便于对文本数据的获取,返回的时候只返回回车符之前的数据内容,并不返回回车符。当返回null时,表示读到文件末尾。

    byte[] buf=new byte[fis.available()];//定义一个刚刚好的缓冲区,不用再循环了

    (建议在文件小的前提下使用,如若过大还是使用数组的1024倍较合适)

    11111111—提升到int型(11111111 11111111 11111111 11111111)仍是-1,只要在前面补0-1&255)—25500000000 00000000 00000000 11111111),既可以保留原字节数据不变,又可以避免-1的出现。

    System.setIn()//重新分配“标准”输入流。    System.setOut()// 重新分配“标准”输出流。 

     

    相当于复制文件getParent()方法返回的是绝对路径中的父目录,若File f=new File(“a.txt”);getParent()则返回null

    File f1=new File(“C:\text.java”);File f2=new File(“D:\hahah.java”);f.renameTo(f1);//true                renameTo()方法类似于剪切 

    package practice;

    import java.io.BufferedWriter;

    import java.io.File;

    import java.io.FileWriter;

    import java.util.ArrayList;

    import java.util.List;

    public class JavaFileList {

    public static void main(String[] args) {

    File dir=new File("f:/java"); 

    List<File> list=new ArrayList<File>();

    fileToList(dir, list);

    File file=new File(dir,"javaList.txt");

    writeToFile(list, file.toString());   

    public static void fileToList(File dir,List<File> list){

    File[] files=dir.listFiles();

    for(File file:files){

    if(file.isDirectory()){

    fileToList(file,list);

    }else{

    if(file.getName().endsWith(".java"))

    list.add(file);

    }

    }

    }

    public static void writeToFile(List<File> list,String javaListFile){

    BufferedWriter bufw=null;

    try{

    bufw=new BufferedWriter(new FileWriter(javaListFile));

    for(File f:list){

    String path=f.getAbsolutePath();

    bufw.write(path);

    bufw.newLine();

    bufw.flush();

    }

    }catch(Exception e){

    e.printStackTrace();

    }finally{

    try

    if(bufw!=null){

    bufw.close();

    }

    }catch(Exception e){

    e.printStackTrace();

    }

    }

    }

    } 

     

    package practice;

    //Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。

    //属性列表中每个键及其对应值都是一个字符串。

    import java.io.BufferedReader;

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

    import java.io.FileReader;

    import java.io.IOException;

    import java.util.Properties;

    import java.util.Set;

    public class PropertiesDemo {

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

    setAndGet();

    method_1();

    loadDemo();

    }

    public static void setAndGet(){

    Properties prop=new Properties();

    prop.setProperty("zhangsan", "30");

    prop.setProperty("lisi", "39");

    // String value=prop.getProperty("lisi");

    //stringPropertyNames()返回此属性列表中的键集,其中该键及其对应值是字符串,

    //如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。

    Set<String> names=prop.stringPropertyNames();

    for(String s:names){

    System.out.println(s+":"+prop.getProperty(s));// 用指定的键在此属性列表中搜索属性

    }

    }

    public static void method_1() throws IOException{

    BufferedReader bufr=new BufferedReader(new FileReader("info.txt"));

    String line=null;

    Properties prop=new Properties();

    while((line=bufr.readLine())!=null){

    String[] arr=line.split("=");

    prop.setProperty(arr[0],arr[1]);

    }

    bufr.close();

    System.out.println(prop);

    }

    public static void loadDemo() throws IOException{

    Properties prop=new Properties();

    FileInputStream fis=new FileInputStream("info.txt");

    prop.load(fis);//从输入流中读取属性列表(键和元素对)

    prop.setProperty("wangwu", "39");//只改变内存的结果,不能改变文件本身

    FileOutputStream fos=new FileOutputStream("info.txt");

    prop.store(fos, "haha");// 以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,

    //将此 Properties 表中的属性列表(键和元素对)写入输出流。

    //System.out.println(prop);

    prop.list(System.out);//将属性列表输出到指定的输出流

    fos.close();

    fis.close();

    }

    package practice;

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.util.Properties;

    public class RunCount {

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

    Properties prop=new Properties();

    File file=new File("count.ini");

    if(!file.exists()){

    file.createNewFile();

    }

    FileInputStream fis=new FileInputStream(file);

    prop.load(fis);

    int count=0;

    String value=prop.getProperty("time");

    if(value!=null){

    count=Integer.parseInt(value);

    if(count>=5){

    System.out.println("您好,使用次数已到,拿钱");

    return;

    }

    }

    count++;

    prop.setProperty("time", count+"");

    FileOutputStream fos=new FileOutputStream(file);

    prop.store(fos, "");

    }

    }

    将多个文件合并至一个文件中

    package practice;

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.SequenceInputStream;

    import java.util.Enumeration;

    import java.util.Vector;

    public class SequenceDemo{

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

    //Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引

    //进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建

    //Vector 后进行添加或移除项的操作。

    Vector<FileInputStream> v=new Vector<FileInputStream>();

    v.add(new FileInputStream("e:/1.txt"));//将指定元素添加到此向量的末尾

    v.add(new FileInputStream("e:/2.txt"));

    v.add(new FileInputStream("e:/3.txt"));

    //实现 Enumeration 接口的对象,它生成一系列元素,一次生成一个。

    //连续调用 nextElement 方法将返回一系列的连续元素。

    Enumeration<FileInputStream> en=v.elements();// 返回此向量的组件的枚举

    SequenceInputStream sis=new SequenceInputStream(en);

    FileOutputStream fos=new FileOutputStream("e:/4.txt");

    byte[] buf=new byte[1024];

    int len=0;

    while((len=sis.read(buf))!=-1){

    fos.write(buf,0,len);

    }

    fos.close();

    sis.close();

    }

    }

    博客园:师妹开讲啦

    切割、合并文件

    package practice;

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.SequenceInputStream;

    import java.util.ArrayList;

    import java.util.Enumeration;

    import java.util.Iterator;

    public class SplitFile {

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

    // splitFile();

    merge();

    }

    public static void merge() throws IOException{

    ArrayList<FileInputStream> a1=new ArrayList<FileInputStream>();

    for(int x=1;x<=5;x++){

    a1.add(new FileInputStream("e:/"+x+".part"));

    }

    final Iterator<FileInputStream> it=a1.iterator();

    Enumeration<FileInputStream> en=new Enumeration<FileInputStream>(){

    public boolean hasMoreElements(){

    return it.hasNext();

    }

    public FileInputStream nextElement(){

    return it.next();

    }

    };

    SequenceInputStream sis=new SequenceInputStream(en);

    FileOutputStream fos=new FileOutputStream("e:/0.jpg");

    byte[] buf=new byte[1024];

    int len=0;

    while((len=sis.read(buf))!=-1){

    fos.write(buf,0,len);

    }

    fos.close();

    sis.close();

    }

    public static void splitFile() throws IOException{

    FileInputStream fis=new FileInputStream("吴亦凡.jpg");

    FileOutputStream fos=null;

    byte[] buf=new byte[1024*10];

    int len=0;

    int count=1;

    while((len=fis.read(buf))!=-1){

    fos=new FileOutputStream("e:/"+(count++)+".part" );

    fos.write(buf,0,len);

    fos.close();

    }

    fis.close();

    }

    }

    操作对象ObjectInputStreamObjectOutputStream需要实现Serializable接口

    (写入文件的信息看不懂)

    静态变量不能实现序列化

    非静态不想实现序列化则可在前加:transient//transient int age;

    一般在实现对象流的时候,对象实体的文件以“.object”为后缀名

    -----------管道流:PipedInputStream和PipedOutputStream与线程结合使用

    RandomAccessFile该类不算是IO体系中的子类,而是直接继承自Object,但它是IO包中的成员,因为它具备读和写功能。内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。

    该类只能操作文件,而且操作文件还有模式,只读r,读写rw等,而且该对象的构造函数要操作的文件不存在会自动创建。如果存在则不会覆盖。

    如果模式为只读,不会创建文件,会去读取一个已存在的文件,如果该文件不存在则会出现异常。

    一个中文两个字节

    RandomAccessFile raf=new RandomAccessFile(“ran.txt”,”r”);//r:只读、rw:读写、

    Seek()//设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取  或写入操作。既可往前跳又可往后跳

    skipBytes()// 尝试跳过输入的 n 个字节以丢弃跳过的字节(只可往前跳)

    DataInputStream和DataOutputSteam用于操作基本数据类型的数据的对象。

    //写入文件的信息看不懂、读取时必须按写入的顺序读

    “你好”的Gbk文件用utf-8解码结果是??

    “你好”的Utf_8文件用gbk解码结果是三个别的文字

    编码:字符串变成字节数组String-byte[];str.getBytes(charsetName)

    解码:字节数组变成字符串byte[]-String:new String(byte[],charsetName);

    Integet.toBinaryString(b)将数值b转换成二进制,若只想要后八位则b&255

        

        

  • 相关阅读:
    曲禮上第一
    Flink 侧输出流 SideOutput
    Flink ProcessFunction API自定义事件处理
    Kafka对接Flume
    Kafka 自定义拦截器
    Kafka 消费者API
    Kafka 生产者API
    luoguP2137 Gty的妹子树 分块+主席树+DFS序
    Codeforces Round #650 (Div. 3)
    LOJ#504. 「LibreOJ β Round」ZQC 的手办 线段树+堆
  • 原文地址:https://www.cnblogs.com/xiaoshimei/p/6200744.html
Copyright © 2011-2022 走看看