• 初学io


    IO流:

     

      01.File

    创建文件

        //创建文件夹
        private static void mkdirs() {
            System.out.println("请您输入创建的文件夹名称:(默认是E:/)");
            String fileName = input.next();
            //创建File对象
            File file=new File("E:/"+fileName);
            if (file.mkdirs()){
                System.out.println("创建成功");
            }else{
                System.out.println("创建失败");
            }
    }

        //创建文件

        private static void createNewFile() {
            System.out.println("请您输入文件的名称:(默认是E:/)");
    
            String fileName = input.next();
    
            //创建File对象
    
            File file=new File("E:/"+fileName);
    
            if (file.exists()){  //文件已经存在
    
                System.out.println("该文件已经存在!");
    
            }else{
    
                try {
    
                 boolean  flag= file.createNewFile();
    
                 if (flag){
    
                     System.out.println("文件创建成功!");
    
                 }else{
    
                     System.out.println("文件创建失败!");
    
                   }
    
                } catch (IOException e) {
    
                    e.printStackTrace();
    
                }
            }
        }

     

     删除文件

      //修改文件

        private static void updateFile() {
            System.out.println("请您输入需要修改文件的名称:(默认是E:/)");
            String oldFileName = input.next();
            System.out.println("请您输入文件的新名称:(默认是E:/)");
            String newFileName = input.next();
            //创建File对象
            File oldFile=new File("E:/"+oldFileName);
            File newFile=new File("E:/"+newFileName);
            if(oldFile.renameTo(newFile)){
                System.out.println("修改成功");
    
            }else{
                System.out.println("修改失败");
    
            }
        }

     

     修改文件 

      //修改文件
        private static void updateFile() {
            System.out.println("请您输入需要修改文件的名称:(默认是E:/)");
            String oldFileName = input.next();
            System.out.println("请您输入文件的新名称:(默认是E:/)");
            String newFileName = input.next();
            //创建File对象
            File oldFile=new File("E:/"+oldFileName);
            File newFile=new File("E:/"+newFileName);
            if(oldFile.renameTo(newFile)){
                System.out.println("修改成功");
            }else{
                System.out.println("修改失败");
            }
        }

     

    显示文件信息

       // 查询文件夹下所有的文件列表
        private static void findFileList() {
            System.out.println("请您输入查询的文件夹名称:(默认是E:/)");
            String fileName = input.next();
            //创建File对象
            File file=new File("E:/"+fileName);
            File[] files = file.listFiles();
            int dirNums=0;
            int fileNums=0;
            //遍历集合
            for (File f:files){
                if (f.isDirectory()){
                    dirNums++;
                }
                if (f.isFile()){
                   fileNums++;
                    System.out.println(f.getName());
                }
            }
            System.out.println("有多少个文件夹?"+dirNums);
            System.out.println("有多少个文件?"+fileNums);
        }

     

     

      02.字节流     

         InputStream(输入)        OutputStream(输出)  基类
    
     都不能实例化
    
      public static void main(String[] args) {
            //创建输入流和输出流对象
            InputStream   inputStream=null;
            OutputStream   outputStream=null;
            try {
                inputStream=new FileInputStream("e:/a.txt");
                // true 代表是否向文件中拼接,不删除之前的内容
                outputStream=new FileOutputStream("e:/a.txt",true);
                //先向文件写入内容
                outputStream.write("54321".getBytes()); //outputStream.flush();  自己没有实现
                // read 方法将返回0-255之间的数字 如果流读到了最后,将返回-1
                 int num=0;
               while ((num=inputStream.read())!=-1){
                   System.out.println((char)num);
               }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    inputStream.close();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

     

     

      03.字符流  

       Reader            Writer

        public static void main(String[] args) {
            //创建输入和输出流
            Reader reader=null;
            Writer writer=null;
            try {
                reader=new FileReader("e:/a.txt");
                writer=new FileWriter("e:/a.txt",true);
                writer.write("大家辛苦了1111!");
                writer.flush();  // 清空缓冲区
                writer.write("大家辛苦了4444!");
                writer.close();
                 //读取
                // 创建一次性读取多少个字符
                char [] data=new char[1024];
                 int num=0;
                 StringBuffer sb=new StringBuffer();
               while((num=reader.read(data))!=-1)  {
                   sb.append(data);
               }
                System.out.println(sb.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

      04.缓冲流

          BufferReader       BufferWriter 不单独使用

      一般和Reader  Writer 联用   在debug的情况下能看清楚Flush的作用

    public static void main(String[] args) {
            //创建输入和输出流
            Reader reader=null;
            Writer writer=null;
            BufferedReader  br=null;
            BufferedWriter bw=null;
            try {
                writer=new FileWriter("e:/a.txt",true);
                bw=new BufferedWriter(writer); //封装
                bw.write("大家辛苦了!");
                bw.newLine();  //换行
                bw.write("大家别眨眼!");
                bw.flush();
                bw.write("大家别眨眼22!");
                bw.write("大家别眨眼33!");
                bw.close();
                writer.close();  //如果不关闭  后续两句话没法获取
                //读取
                reader=new FileReader("e:/a.txt");
                br=new BufferedReader(reader);//封装
                String line=null;
                StringBuffer sb=new StringBuffer();
                while ((line=br.readLine())!=null){
                    sb.append(line);
                }
                System.out.println(sb.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    br.close();
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

     

     

      05.二进制流       

      DataInputStream    DataOutputStream

    不单独使用  一般需要与 InputStream   OutputStream 联用

    public static void main(String[] args) {
            //创建输入流和输出流对象
            InputStream inputStream=null;
            OutputStream outputStream=null;
            DataInputStream  dis=null;
            DataOutputStream dos=null;
            try {
                //获取了输入流   猫咪进内存了
                inputStream=new FileInputStream("e:/dog.jpg");
                dis=new DataInputStream(inputStream);
                //获取输出流
                outputStream=new FileOutputStream("e:/u1/cat.jpg");
                dos=new DataOutputStream(outputStream);
                //先读取
                int num=0;
                 while ((num=dis.read())!=-1){
                     dos.write(num);  //复制
                 }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {  //释放资源
                try {
                    dos.close();
                    dis.close();
                    outputStream.close();
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

      06.序列化和反序列化

     ObjectInputStream  ObjectOutputStream

    序列化:序列化(Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。

    持久化:持久化是将程序数据在持久状态和瞬时状态间转换的机制。

    注意 实体类需要接口Serializable 要不然无法序列化

     

     static Scanner  input=new Scanner(System.in);
    
        //创建需要的输入和输出流对象
    
        static   InputStream inputStream=null;
    
        static  OutputStream outputStream=null;
    
        static ObjectInputStream objectInputStream=null;
    
        static ObjectOutputStream  objectOutputStream=null;
    
     
    
        public static void main(String[] args) {
    
             //注册   序列化
    
            //register();
    
            //登录  反序列化
    
            login();
    
    }
    
    //注册
    
        private static void register()  {
    
            User user=new User();
    
            System.out.println("请输入您的用户名:");
    
            user.setUserName(input.next());
    
            System.out.println("请输入您的密码:");
    
            user.setPassword(input.next());
            try {
                outputStream=new FileOutputStream("e:/user.txt");
                objectOutputStream=new ObjectOutputStream(outputStream);
                //把对象输出到文件中
                objectOutputStream.writeObject(user);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    objectOutputStream.close();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
     
        //登录
        private static void login() {
            try {
                inputStream=new FileInputStream("e:/user.txt");
                objectInputStream=new ObjectInputStream(inputStream);
                //读取对象
                User user= (User) objectInputStream.readObject();
                System.out.println(user);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
    
                try {
                    objectInputStream.close();
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }  

     

     

    NIO:

    非堵塞io  全称new io

    Java NIO: Channels and Buffers(通道和缓冲区)

    为了理解Buffer的工作原理,需要熟悉它的三个属性:

    • capacity
    • position
    • limit

    position和limit的含义取决于Buffer处在读模式还是写模式。不管Buffer处在什么模式,capacity的含义总是一样的。

    这里有一个关于capacity,position和limit在读写模式中的说明,详细的解释在插图后面。

     

    capacity

    作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity个byte、long,char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。

    position

    当你写数据到Buffer中时,position表示当前的位置。初始的position值为0.当一个byte、long等数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity – 1.

    当读取数据时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0. 当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。

    limit

    在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下,limit等于Buffer的capacity。

    当切换Buffer到读模式时, limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)

     

    Buffer的分配

    要想获得一个Buffer对象首先要进行分配。 每一个Buffer类都有一个allocate方法。下面是一个分配48字节capacity的ByteBuffer的例子。

    1

    ByteBuffer buf = ByteBuffer.allocate(48);

    这是分配一个可存储1024个字符的CharBuffer:

    1

    CharBuffer buf = CharBuffer.allocate(1024);

     

    向Buffer中写数据

    写数据到Buffer有两种方式:

    • 从Channel写到Buffer。
    • 通过Buffer的put()方法写到Buffer里。

    从Channel写到Buffer的例子

    1

    int bytesRead = inChannel.read(buf); //read into buffer.

    通过put方法写Buffer的例子:

    1

    buf.put(127);

    put方法有很多版本,允许你以不同的方式把数据写入到Buffer中。例如, 写到一个指定的位置,或者把一个字节数组写入到Buffer。 更多Buffer实现的细节参考JavaDoc。

    flip()方法

    flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。

    换句话说,position现在用于标记读的位置,limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。

    从Buffer中读取数据

    从Buffer中读取数据有两种方式:

    1. 从Buffer读取数据到Channel。
    2. 使用get()方法从Buffer中读取数据。

    从Buffer读取数据到Channel的例子:

    1

    int bytesWritten = inChannel.write(buf);

     

     

    使用get()方法从Buffer中读取数据的例子

    1

    byte aByte = buf.get();

     

     

     

     

     

    01他是基于缓冲区对数据进行读取或者是写入

    02通道是双向的,流是单向的

    03可以异步的读写

    常用的实现

    1.Filechannel:从文件中读写数据

    2.DatagrarmChannel:通过UDP读写网络中的数据Udp:不安全 非链接 快

    3.SocketChannel:通过TCp读写网络中的数据  Tcp: 安全  链接  慢

    4.serverSocketChannel:可以监听新来的Tcp链接,每进来一个都会创建一个新的serverSocketChannel

    内存映射

    就是把文件映射到电脑的内存中,通过操作内存从而到达操作文件的目的

    内存中操作速度是最快的!

     Java中的读取文件方式

    1.RandomAccessFile    随机读取,速度最慢 可以设置读写

    2.FileInputStream         流的方式读取

    3.BufferReader            缓存的方式读取

    4.MappedByteBuffer   内存映射,速度最快

     

    内存映射的三种模式 :MapMode

    1. READ_ONLY  :对缓冲区的内容只读
    2. READ_WRITE   :对缓冲区的内容读写
    3. PRIVATE:      只会对缓冲区的内容修改,不会影响到真实文件

    通常适用于文件的读取! 一般不会涉及到文件袋写入

     

    文件锁

    1. FileLock 基于FIleChannel对文件提供锁的功能!
      1. 共享锁 共享读的操作 只能有一个写的操作 适合读取数据

    为了防止其他线程使用独占锁

    1. 独占锁 读写不能同时 只能一个读或者写   适合写数据

    Lock(); 没有参数的是独占锁 有参数的是共享锁也有可能是独占锁

     

    Nio:将buffer写入 Channel

      

      public static void main(String[] args) {
            System.out.println("d");
            //创建数组
            String[] bytee = {"dd", "dd", "dd"};
            //创建文件对象 自动创建
            File file = new File("d:/a.txt");
    //        创建输出流对象
            FileOutputStream fos = null;
    //        创建管道对应的实现类
            FileChannel fileChannel = null;
    
            try {
                fos = new FileOutputStream(file);
    //          获取管道
                fileChannel = fos.getChannel();
    //            创建缓冲区
                ByteBuffer buffer = ByteBuffer.allocate(1024);
    //            循环出数组的数据
                for (String s : bytee) {
    //               将训话你的数据写缓冲区
                    System.out.println(s.getBytes() );
                    buffer.put(s.getBytes());
                }
    //           从写模式切换读模式
                buffer.flip();
    //            正在的写入
                fileChannel.write(buffer);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fileChannel.close();
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
    
        }
    
     

     

     

    Nio2:将文件内容复制到另一个文件里面

     
      //从文件a到文件b传数据
    
        public static void main(String[] args) {
    
    //创建需要的两个文件
    
            File afile = new File("d:/a.txt");
    
            File bfile = new File("d:/b.txt");
    
    //        创建输出流对象
    
            FileInputStream fileInputStream = null;
    
            FileOutputStream fileOutputStream = null;
    
    //        创建管道对应的实现类
    
            FileChannel inputchannel = null;
    
            FileChannel outputchannel = null;
    
            try {
    
                fileInputStream = new FileInputStream(afile);
    
                fileOutputStream = new FileOutputStream(bfile);
    
    //          获取管道
    
                inputchannel = fileInputStream.getChannel();
    
                outputchannel = fileOutputStream.getChannel();
    
    //            创建缓冲区
    
                ByteBuffer buffer = ByteBuffer.allocate(1024);
    
    //           从写模式切换读模式
    
                int num = 0;
    
                while ((num = inputchannel.read(buffer)) != -1) {
    
    //               切换模式
    
                    buffer.flip();
    
                    //写入到b文件里面
    
                    outputchannel.write(buffer);
    
                    //清空缓存区
    
                    buffer.clear();
    
                    System.out.println(buffer);
    
                    System.out.println(num);
    
                }
    
    
    
    //            正在的写入
    
            } catch (Exception e) {
    
                e.printStackTrace();
    
            } finally {
    
                try {
    
                    inputchannel.close();
    
                    outputchannel.close();
    
                    fileInputStream.close();
    
                    fileOutputStream.close();
    
                } catch (Exception e) {
    
                    e.printStackTrace();
    
                }
    
            }
        }

     

    Nio3:比较内存映射和io的时间

      public static void main(String[] args) {
    
            FileChannel channel = null;
    
            try {
    
    //            找打指定的文件并且设置读写模式
    
                RandomAccessFile file = new RandomAccessFile("d:/a.txt", "rw");
    
    //创建管道
    
                channel = file.getChannel();
    
                MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
    
                ByteBuffer byteBuffer1 = ByteBuffer.allocate(1204);
    
                byte[] bytes = new byte[1024];
    
                long length = file.length();
    
                long beginTime = System.currentTimeMillis();
    
                for (int i = 0; i < length; i += 1024) {
    
                    if (length - i > 1024) {
    
                        buffer.get(bytes);
    
                    } else {
    
                        buffer.get(new byte[(int) (length - i)]);
    
                    }
    
                }
    
                long endTime = System.currentTimeMillis();
    
                System.out.println("使用内存映射时间" + (endTime - beginTime));
    
                System.out.println("-------------------------------------------------------");
    
                beginTime = System.currentTimeMillis();
    
                while (channel.read(byteBuffer1) > 0) {
    
                    byteBuffer1.flip();
    
                    byteBuffer1.clear();
    
                }
    
                endTime = System.currentTimeMillis();
    
                System.out.println("使用普通io时间" + (endTime - beginTime));
    
            } catch (Exception e) {
    
                e.printStackTrace();
    
            }
    
        }

     

     

     

     

     

  • 相关阅读:
    BZOJ.4293.[PA2015]Siano(线段树)
    洛谷.T21778.过年(线段树 扫描线)
    HDU.6155.Subsequence Count(线段树 矩阵)
    BZOJ.3687.简单题(bitset)
    var let const的区别
    2、electron进程
    1、Electron入门HelloWorld案例
    JUnit@Before失效
    十一、Thymeleaf的基础使用
    九、SpringBoot集成Thymeleaf模板引擎
  • 原文地址:https://www.cnblogs.com/liehuonanjue/p/9271901.html
Copyright © 2020-2023  润新知