Java中实现顺序IO

顺序IO和随机IO

对于磁盘的读写分为两种模式,顺序IO和随机IO。 随机IO存在一个寻址的过程,所以效率比较低。而顺序IO,相当于有一个物理索引,在读取的时候不需要寻找地址,效率很高。

网上盗了一个图(侵权删)


Java中的随机读写

在Java中读写文件的方式有很多种,先总结以下3种方法:

  1. FileWriter和FileReader
public static void fileWrite(String filePath, String content) {
            File file = new File(filePath);
            //创建FileWriter对象
            FileWriter writer = null;
            try {
                 //如果文件不存在,创建文件
                 if (!file.exists())
                      file.createNewFile();
                 writer = new FileWriter(file);
                 writer.write(content);//写入内容
                 writer.flush();
                 writer.close();
            } catch (IOException e) {
                 e.printStackTrace();
            }
       }
          
       public static void fileRead(String filePath) {
            File file = new File(filePath);
            if (file.exists()) {
                 try {
                      //创建FileReader对象,读取文件中的内容
                      FileReader reader = new FileReader(file);
                      char[] ch = new char[1];
                      while (reader.read(ch) != -1) {
                           System.out.print(ch);
                      }
                      reader.close();
                 } catch (IOException ex) {
                      ex.printStackTrace();
                 }
                    
            }
       } 

  1. BufferedReader和BufferedWriter BufferedReader和BufferedWriter与FileWriter和FileReader代码的写法一致,Buffer也多了一个读取一行字符的操作。
  public class BuffredRWHelper {
       public static void fileWrite(String filePath, String content) {
            File file = new File(filePath);
            //创建FileWriter对象
            BufferedWriter writer = null;
            try {
                 //如果文件不存在,创建文件
                 if (!file.exists())
                      file.createNewFile();
                 writer = new BufferedWriter(new FileWriter(file));
                 writer.write(content);//写入内容
                 writer.flush();
                 writer.close();
            } catch (IOException e) {
                 e.printStackTrace();
            }
       }
          
       public static void fileRead(String filePath) {
            File file = new File(filePath);
            if (file.exists()) {
                 try {
                      //创建FileReader对象,读取文件中的内容
                      BufferedReader reader = new BufferedReader(new FileReader(file));
                      String line;
                      while ((line = reader.readLine()) != null) {
                           System.out.print(line);
                      }
                      reader.close();
                 } catch (IOException ex) {
                      ex.printStackTrace();
                 }
                    
            }
       }
  } 

  1. FileInputStream和FileOutputStream 使用Stream的形式是最原始的方式,以字节数组为中间的中转缓解
public static void fileWrite(String filePath, String content) {
     FileOutputStream outputStream = null;
     try {
         File file = new File(filePath);
         boolean isCreate = file.createNewFile();//创建文件
         if (isCreate) {
             outputStream = new FileOutputStream(file);//形参里面可追加true参数,表示在原有文件末尾追加信息
             outputStream.write(content.getBytes());
         }else {
             outputStream = new FileOutputStream(file,true);//表示在原有文件末尾追加信息
             outputStream.write(content.getBytes());
         }
     } catch (Exception e) {
         e.printStackTrace();
     } finally {
         try {
             outputStream.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }
	
 public static void fileRead(String filePath) {
     File file = new File(filePath);
     if (file.exists()) {
         try {
             //创建FileInputStream对象,读取文件内容
             FileInputStream fis = new FileInputStream(file);
             byte[] bys = new byte[1024];
             while (fis.read(bys, 0, bys.length) != -1) {
                 //将字节数组转换为字符串
                 System.out.print(new String(bys, StandardCharsets.UTF_8));
             }
         } catch (IOException ex) {
             ex.printStackTrace();
         }
			
     }
 } 

Java中的顺序读写

上面的对文件的读写都是随机读写,如果用来写比较小的日志文件还能满足要求,如果用来操作一个文件的读写,那可能带来很大的性能消耗。

顺序IO的读写在中间件使用的很频繁,尤其是在队列中。几乎所有的队列(kafka,qmq等使用文件存储消息)都采用了顺序IO读写。

与随机读写不同的是,顺序读写是优先分配一块文件空间,然后后续内容追加到对应空间内。

在使用顺序IO进行文件读写时候,需要知道上次写入的地方,所以需要维护一个索引或者轮询获得一个没有写入位置。

public static long fileWrite(String filePath, String content, int index) {
     File file = new File(filePath);
     RandomAccessFile randomAccessTargetFile;
     MappedByteBuffer map;
     try {
          randomAccessTargetFile = new RandomAccessFile(file, "rw");
          FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
          map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, (long) 1024 * 1024 * 1024);
          map.position(index);
          map.put(content.getBytes());
          return map.position();
     } catch (IOException e) {
          e.printStackTrace();
     } finally {
     }
     return 0L;
}

public static String fileRead(String filePath, long index) {
     File file = new File(filePath);
     RandomAccessFile randomAccessTargetFile;
     MappedByteBuffer map;
     try {
          randomAccessTargetFile = new RandomAccessFile(file, "rw");
          FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
          map = targetFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, index);
          byte[] byteArr = new byte[10 * 1024];
          map.get(byteArr, 0, (int) index);
          return new String(byteArr);
     } catch (IOException e) {
          e.printStackTrace();
     } finally {
     }
     return "";
}

(本文完)

作者:付威 博客地址:http://blog.laofu.online 如有任何知识产权、版权问题或理论错误,还请指正。 本文是付威的网络博客原创,自由转载-非商用-非衍生-保持署名,请遵循:创意共享3.0许可证

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Netty01--- Netty实现简单通信

    这个Demo的功能是客户端向服务端发送一个Hello Netty的消息,然后服务端又把消息返回给客户端

    付威
  • Java发送邮件(含附件)

    前几天写了一个Java发送邮件的帮助类i,可以发送QQ和163的邮箱,也可以发送附件,写个一个主要的方法,其他的可以自己封装。代码如下:

    付威
  • Java反射和注解

    反射是指在运行的状态,对于任意一个类,都能够知道类里面的所有的属性和方法,并能够进行属性的赋值和方法的调用 。 在java中使用java.lang下面的Clas...

    付威
  • [PHP] 重回基础(IO流)

    获取FileWriter对象,new出来,构造参数:String的文件名;此时会在指定目录下创建出文件,如果已存在,将会被覆盖;这个方法会抛出IOExcepti...

    陶士涵
  • java读写file

    private static String encoding = "utf-8"; public static void readTxt(Strin...

    Ryan-Miao
  • aspose-words java word 转pdf

    和谐版jar包 加激活 去除水印 转换从此无限制 就算是在服务器上也不需要安装其他工具 目前最好 使用 方便快捷 jar包下载地址 链接: https://pa...

    崔笑颜
  • java练习本(2019-07-21)

    “ Love is the greatest refreshment in life. ”

    微笑的小小刀
  • java:Set,Map排序输出到Writer

    一般来说java.util.Set,java.util.Map输出的内容的顺序并不是按key的顺序排列的,但是java.util.TreeMap,java.ut...

    用户1148648
  • 聊聊flink的log.file配置

    flink-release-1.6.2/flink-dist/src/main/flink-bin/conf/log4j.properties

    codecraft
  • PHP 框架 Swoole

    PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,...

    lilugirl

扫码关注云+社区

领取腾讯云代金券