IO流《笔记》

IO流

File类的使用

/* File类的使用
*
* 1.File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)
* 2.File类声明在java.io包下
* 3.File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,
*      并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。
* 4.后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”。
*/
public class File {


    //如何创建File类的实例
    //public File(String pathname)
    //public File(String parent,String child)
    //以parent为父路径,child为子路径创建File对象。
    //public File(File parent,String child)
    //根据一个父File对象和子文件路径创建File对象

    //相对路径:相较于某个路径下,指明的路径。
    //绝对路径:包含盘符在内的文件或文件目录的路径

    @Test
    public void test1(){
        java.io.File file = new java.io.File("hello.text");//相对于当面meodule
    }

/* public String getAbsolutePath():获取绝对路径
 public String getPath() :获取路径
 public String getName() :获取名称
 public String getParent():获取上层文件目录路径。若无,返回null
 public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
 public long lastModified() :获取最后一次的修改时间,毫秒值

如下两个方法适用于文件目录
 public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
 public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
*/

    @Test
    public void test2(){

    }

    //File类的重命名功能
    // public boolean renameTo(File dest):把文件重命名为指定的文件路径
    //比如:file1.renameTo(file2)为例:
    //      要想保证返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在
/* File类的判断功能
 public boolean isDirectory():判断是否是文件目录
 public boolean isFile() :判断是否是文件
 public boolean exists() :判断是否存在
 public boolean canRead() :判断是否可读
 public boolean canWrite() :判断是否可写
 public boolean isHidden() :判断是否隐藏
 File类的创建功能
 public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false
 public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。
如果此文件目录的上层目录不存在,也不创建。
 public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建
 File类的删除功能
 public boolean delete():删除文件或者文件夹

* */
}

复习

  • 如何遍历Map的key集,value集,key-value集,使用上泛型

    Map<String,Integer> map = new HashMap<>();
    map.put();
    ...
    //遍历key
    Set<String> keySet = map.keySet();
    for(String key : keySet){
    		System.out.println(key);
    }
    //遍历values
    Collection<Integer> values = map.values();
    Iterator<Tnteger> iterator = values.iterator();
    while(iterator.hasNext()){
    		System.out.println(iterator.next());
    }
    //遍历key-value
    Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
    Iterator<Map.Entry<String,Integer>> iterator = entrySet.iterator();
    while(iterator.hasNext()){
    		Map.Entry<String,Integer> entry = iterator.next();
        	String key = entry.getKey();
        	Integer values = entry.getValues();
        	System.out.println(key + "----------" + values);
    }
    
  • 写出使用Iterator和增强for循环遍历List的代码,使用上泛型

  • 提供一个方法,用于遍历获取HashMap<String,String>中所有的value,并存放在List中返回,考虑撒谎给你集合中泛型的使用。

    public List<String> getValueList(HashMap<String,String> map){
        ArrayList<String> valueList = new ArrayList<>();
        Collection<String> values = map.values();
        for(String value : values){
            valuesList.add(values);
        }
        return valuesList;
    }
    
  • 创建一个与a.txt文件同目录下的另外一个文件b.txt

    File file1 = new File("d:\\a\\a.txt");
    File file2 = new File(file.getParent(),"b.txt");
    
  • Map接口中的常用方法有哪些

    put (K k,V v);//增
    V remove(K k);//删
    put (K k,V v);//改
    V get(K k);//查
    int size();//长度
    

IO流

  • I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
(抽象基类)字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter
 /* 一、流的分类
 * 1.操作数据单位:字节流、字符流
 * 2.数据的流向:输入流、输入流
 * 3.流的角色:字节流、处理流
 *
 * 二、流的体系结构
 * 抽象基类            节点流(或文件流)          缓冲流(处理流的一种)
 * InputStream         FileInputStream           BufferedInputStream
 * OutputStream        FileOutputStream          BufferedOutputStream
 * Reader              FileReader                BufferedReader
 * Writer              FileWriter                BufferedWriter
 */
public class FileReaderWriterTest {

    public static void main(String[] args) {
        File file = new File("hello.txt");//相较于当前工程下
        System.out.println(file.getAbsoluteFile());

        File file1= new File("day13\\hello.txt");//正确操作
        System.out.println(file1.getAbsoluteFile());
    }


    //将day13下的hello.txt文件内容读入程序中,并输出到控制台
    /*
    * 说明点:
    * 1.read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
    * 2.异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
    * 3.读入的文件一定要存在,否则就会报FileNotFoundException*/
    @Test
    public void testFileReader()  {
        //1.实例化file文件
        FileReader reader = null;
        try {
            File file = new File("D:\\Java\\Thread\\src\\day13\\hello.txt");//相较于当前Module

            //2.提供具体的流
            reader = new FileReader(file);

            //3.数据的读入
            //read():返回读入的一个字符,如果达到文件末尾,返回-1
            int data = reader.read();
            while (data != -1){
                System.out.print((char)data);
                data = reader.read();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //4.流的关闭操作
        try {
            if (reader != null)
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 //对read()操作升级:使用read的重载方法
    @Test
    public void test2()  {
        FileReader fileReader = null;
        try {
            File file = new File("D:\\Java\\Thread\\src\\day13\\hello.txt");
            fileReader = new FileReader(file);

            //读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
            char[] cbuf = new char[5];
            int len;

           while ((len = fileReader.read(cbuf)) != -1){
               //方式一:错误写法
//                for (int i=0; i<cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
               //方式一正确写法
//               for (int i=0; i<len;i++){
//                  System.out.print(cbuf[i]);
//                }
               //方式二错误写法
//               String s = new String(cbuf);
//               System.out.println(s);
               //方式二正确写法
               String ss = new String(cbuf, 0, len);
               System.out.print(ss);
           }

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


    }
/*从内从中写出数据到硬盘的文件里
*
* 说明:
* 1.输入操作,对应的File可以不存在
*       如果不存在,在输入的过程中,会自动创建此文件
*       如果存在:
*               如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件覆盖
*               如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件基础上追加内容
* */

@Test
public void testWriter() throws IOException {
    //1.提供File类的对象,指明写出到的文件
    File file = new File("D:\\Java\\Thread\\src\\day13\\hello1.txt");

    //2.提供FileWriter的对象,用于数据的写入
    FileWriter writer = new FileWriter(file);

    //3.写出的操作
    writer.write("i hava a dream");

    //4.流资源的关闭
    writer.close();
}
//实现文本文件的复制
@Test
public void test3() throws IOException {
    FileReader reader = null;
    FileWriter writer = null;
    try {
        //1.创建File类的对象,指明读入和写出的文件
        File file = new File("D:\\Java\\Thread\\src\\day13\\hello.txt");
        File file1 = new File("D:\\Java\\Thread\\src\\day13\\hello1.txt");

        //2.创建输入流和输出流的对象
        reader = new FileReader(file);
        writer = new FileWriter(file1);
        //3.数据的读入和写出操作
        char[] cbuf = new char[5];
        int len;
        while ((len = reader.read(cbuf)) != -1){
            //每次写出len个字符
            writer.write(cbuf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //4.关闭流资源
        try {
            if (reader != null)
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (writer != null)
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

缓冲流

/* 缓冲流的使用
 *
 * 1.缓冲流:
 * BufferedInputStream
 * BufferedOutputStream
 * BufferedReader
 * BufferedWriter
 *
 *
 * 2.作用:提供流的读取、写入的速度
 *      提高读写速度的原因:内部提供了一个缓冲区
 *
 * 3.处理流:就是“套接”在已有的流的基础上。
 *
* 4.总结:抽象基类    节点流(或文件流)                            缓冲流(处理流的一种)
 *  * InputStream   FileInputStream(read(byte[] buffer))        BufferedInputStream(read(byte[] buffer))
 *  * OutputStream  FileOutputStream(write(byte[] buffer,0,len))BufferedOutputStream(write(byte[] buffer,0,len))
 *  * Reader        FileReader(read(char[] cbuf))               BufferedReader(read(char[] cbuf))
 *  * Writer        FileWriter(write(char[] cbuf,0,len)         BufferedWriter(write(char[] cbuf,0,len)
 */
public class BufferedTest {

    /*
    * 实现非文本文件的复制
    *
    * */
    @Test
    public void test1()  {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1.造文件
            File srcfile = new File("C:\\Users\\Lenovo\\Desktop\\01.jpg");
            File destfile = new File("C:\\Users\\Lenovo\\Desktop\\02.jpg");
            //2.造流
            //2.1造节点流
            FileInputStream inputStream = new FileInputStream((srcfile));
            FileOutputStream outputStream = new FileOutputStream((destfile));
            //2.2造缓冲流
            bis = new BufferedInputStream(inputStream);
            bos = new BufferedOutputStream(outputStream);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //4.资源关闭:先关外面再关里面,但是如果你关闭了外面的,自动里面的就会关闭,所以只用close缓冲流
            if (bis != null)
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (bis != null)
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

        //复制的方法
    public void copy(String srcPath,String destPath){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1.造文件
            File srcfile = new File(srcPath);
            File destfile = new File(destPath);
            //2.造流
            //2.1造节点流
            FileInputStream inputStream = new FileInputStream((srcfile));
            FileOutputStream outputStream = new FileOutputStream((destfile));
            //2.2造缓冲流
            bis = new BufferedInputStream(inputStream);
            bos = new BufferedOutputStream(outputStream);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //4.资源关闭:先关外面再关里面,但是如果你关闭了外面的,自动里面的就会关闭,所以只用close缓冲流
            if (bis != null)
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (bis != null)
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

    }

    @Test
    public void copytesr(){
        long start = System.currentTimeMillis();

        String srcPath = "C:\\Users\\Lenovo\\Desktop\\01.jpg";
        String destPath = "C:\\Users\\Lenovo\\Desktop\\02.jpg";

        copy(srcPath,destPath);
        long end = System.currentTimeMillis();
        System.out.println("复制操作花费的时间为:" + (end - start));
    }
}
/*
* 使用BufferedReader和BufferedWriter实现文本文件的复制
*
*
* */

    @Test
    public void ReaderWritertest()  {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(new File("D:\\Java\\Thread\\src\\day13\\dbcp.txt")));
            bw = new BufferedWriter(new FileWriter(new File("D:\\Java\\Thread\\src\\day13\\dbcp1.txt")));
            //读写操作
            //方式一:使用char[]数组
            char[] buffer = new char[1024];
            int len;
            while ((len = br.read(buffer)) != -1){
                bw.write(buffer,0,len);
            //方式二:使用String
            String data;
            while ((data = br.readLine())!= null){
                //方法一:
                //bw.write(data + "\n");//data中不包括换行符

                //方法二:
                bw.write(data);//data中不包括换行符
                bw.newLine();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) br.close();
                if (bw != null) bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

练习

  • 文件的加密

  • public class PicTest {
    
        //图片的加密
        @Test
        public void test1(){
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                fis = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\01.jpg");
                fos = new FileOutputStream("C:\\Users\\Lenovo\\Desktop\\02.jpg");
    
                byte[] buffer = new byte[20];
                int len;
                while ((len = fis.read(buffer)) != -1){
                    for (int i = 0; i <len ; i++) {
                        buffer[i] = (byte) (buffer[i] ^ 5);
                    }
                    fos.write(buffer,0,len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            try {
                if (fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        //图片的解密
        @Test
        public void test2(){
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                fis = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\02.jpg");
                fos = new FileOutputStream("C:\\Users\\Lenovo\\Desktop\\03.jpg");
    
                byte[] buffer = new byte[20];
                int len;
                while ((len = fis.read(buffer)) != -1){
                    for (int i = 0; i <len ; i++) {
                        buffer[i] = (byte) (buffer[i] ^ 5);
                    }
                    fos.write(buffer,0,len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            try {
                if (fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }
    
  • 获取文本上每个字符出现的次数

转换流

/*
 * 1.转换流:
 *      InputStreamReader:将InputStream转换为Reader(字节输入转换为字符输入)
 *      OutputStreamWriter:将Writer转换为OutputStream(字符输出转换为字节输出)
 *      属于字符流
 * 2.作用:提供字节流和字符流之间的转换
 * 3.解码:字节、字节数组  ----》字符数组、字符串
 *   编码:字符数组、字符串 ----》字节、字节数组
 * 4.字符集
 * 常见的编码表
 *  ASCII:美国标准信息交换码。
 *  用一个字节的7位可以表示。
 *  ISO8859-1:拉丁码表。欧洲码表
 *  用一个字节的8位表示。
 *  GB2312:中国的中文编码表。最多两个字节编码所有字符
 *  GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
 *  Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的
 * 字符码。所有的文字都用两个字节来表示。
 *  UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。
 *
 */
public class InputStreamReaderTest {

    @Test
    public void test1() throws IOException {
        FileInputStream fis = new FileInputStream("D:\\Java\\Thread\\src\\day13\\dbcp.txt");
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");

        char[] cbuf = new char[20];
        int len;
        while ((len = isr.read(cbuf)) != -1){
            String s = new String(cbuf, 0, len);
            System.out.print(s);
        }
        isr.close();
    }
}

对象流

/* 对象流的使用
 * 1.ObjectInputStream 和ObjectOutputStream
 * 2.作用:  用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可
 *          以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
 * 3.要想一个java对象是可序列化的,需要满足相应的要求,见Person类
 */
public class ObjectInputOutputStreamTest {

    /*
    * 序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
    * 使用ObjectOutputStream实现
    * */
    @Test
    public void test1(){
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            oos.writeObject(new String("我爱天安门"));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
/*
* 反序列化:将磁盘文件中的对象还原为内存中的一个java对象
* 使用ObjectInputStream
* */
    @Test
    public void test2(){
        ObjectInputStream obj = null;
        try {
            obj = new ObjectInputStream(new FileInputStream("object.dat"));
            Object o = obj.readObject();
            String str = (String) o;
            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {

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


    }
}
/* Person类需要满足如下的要求,方可序列化
 *
 * 1.需要实现接口:Serializable
 * 2.需要当前类提供一个全局常量:serialVersionUID
 * 3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须可序列化。
 *      (默认情况下,基本数据类型可系列化)
 */
public class Person implements Serializable {

    public static final long serialVersionUID = 446464L;

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

随机存取文件流

/* RandomAccessFile的使用
 * 1.RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口
 * 2.RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
 * 3.如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建
 *   如果写出的文件存在,则会从文件内容的开头依次进行覆盖
 *
 */
public class RandomAccessFileTest {
   @Test
    public void test1(){
       RandomAccessFile raf1 = null;
       RandomAccessFile raf2 = null;
       try {
           raf1 = new RandomAccessFile(new File("object.dat"), "r");
           raf2 = new RandomAccessFile(new File("object1.dat"), "rw");

           byte[] buffer = new byte[1024];
           int len;
           while ((len = raf1.read(buffer)) != -1){
               raf2.write(buffer,0,len);
           }
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           if (raf1 != null){
               try {
                   raf1.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
           if (raf2 != null){
               try {
                   raf2.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }

           }
       }
   }

   @Test
    public void test2(){

       RandomAccessFile raf1 = null;
       try {
           raf1 = new RandomAccessFile("hello.txt", "rw");

           raf1.write("xyz".getBytes());
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           if (raf1 != null){
               try {
                   raf1.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }


   }
}
/* 4.可以通过相关的操作,可以进行插入操作
*/
   /*
    * 使用RandomAccessFile实现数据的插入效果
    * */

    @Test
    public void test4(){
        RandomAccessFile raf1 = null;
        try {
            raf1 = new RandomAccessFile("hello.txt", "rw");
            raf1.seek(3);//将指针调到角标为3的位置
            //保存指针3后面的所有数据到StringBuilder中
            StringBuilder b = new StringBuilder((int) new File("hello.txt").length());
            byte[] buffer = new byte[20];
            int len;
            while ((len = raf1.read(buffer)) != -1){
                b.append(new String(buffer,0,len));
            }
            //调回指针,写入“xyz”
            raf1.seek(3);
            raf1.write("xyz".getBytes());
            //现在的指针在“z”的后面,将StringBuilder中的数据写入到文件中
            raf1.write(b.toString().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf1 != null){
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值