初学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();

        }

    }

 

 

 

 

 

原文地址:https://www.cnblogs.com/liehuonanjue/p/9271901.html