常用流文件处理

91 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天点击查看活动详情

使用byte,按照字节读取   使用character,按照字符读取 使用reader,按照行读取 使用buffer,缓存读取 使用channel,通道读取 使用内存映射,读取文件

* FileChnel flip --> buffer的三個属性

1. 重放数据 -> 从生成的临时文件(page cache 脏页)变成数据文件

2. 按行读取文件

3. mmap不足如何在生成一个mmap映射文件

* FileChnel flip --> buffer的三個属性

     byte[] buff  //buff即内部用于缓存的数组。

     position //当前读取的位置或者下一次写入的位置

     mark //为某一读过的位置做标记,便于某些时候回退到该位置。

     capacity //初始化时候的容量。

     limit //当写数据到buffer中时,limit一般和capacity相等,当读数据时,

     limit代表buffer中有效数据的长度。

netty中对ByteBuf的增强:

● 简化了缓冲区的读写操作(减少filp操作)

● 动态扩展(倍增+平滑)

● 引用计数,内存回收


 public class ByteBuffTest {
 2 
 3     public static void main(String[] args){
 4         /*******************初始阶段**********************/
 5         ByteBuf buf = Unpooled.buffer(100, 200);
 6         System.out.println("writable bytes " + buf.writableBytes());
 7         System.out.println("readable bytes " + buf.readableBytes());
 8 
 9         /*******************写入数据**********************/
10         String str = "write test";//UTF-8 英文字符占一个字节
11         int length = str.getBytes().length;//因此得到的字节长度为10
12         buf.writeBytes(str.getBytes());
13         System.out.println("writable bytes " + buf.writableBytes());
14         System.out.println("readable bytes " + buf.readableBytes());
15 
16         /*******************读取数据*********************/
17         char c = (char)buf.readByte();//读取第一个字节,并转换成字符打印
18         System.out.println("c:" + c);
19         System.out.println("writable bytes " + buf.writableBytes());
20         System.out.println("readable bytes " + buf.readableBytes());
21 
22         /*******************丢弃已读*********************/
23         buf.discardReadBytes();
24         System.out.println("writable bytes " + buf.writableBytes());
25         System.out.println("readable bytes " + buf.readableBytes());
26 
27     }
28 }

1. 重放数据 -> 从生成的临时文件(page cache 脏页)变成数据文件

public static void recoverVLog(String path, int shardId) {
    // 根据文件的父路径和子路径获取文件
  File vlogTmpFile = new File(path, Filename.vlogTmpFileName(shardId));
  if (!vlogTmpFile.exists()) {
    return;
  }
  // 读取文件流
  try (FileChannel vlogTmpChannel = new FileInputStream(vlogTmpFile).getChannel();
       FileChannel vLogWriter = new FileOutputStream(new File(path, Filename.vlogFileName(shardId)), true).getChannel()) {
    // 4个字节的bytebuffer
    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
    // 循环读取4个字节到buffer
    while (vlogTmpChannel.read(buffer) > 0) {
      // 对同一块区域不断擦写
      buffer.flip(); // 读取buffer的数据limit = position;position = 0;mark = -1;
      vLogWriter.write(buffer); // 写入到新文件
      buffer.clear();
    }

    // safe deletion
    vlogTmpFile.delete();
  } catch (IOException e) {
    e.printStackTrace();
    Throwables.propagate(e);
  }
}

// 这里的size包括重放的和插入的
long vLogFileSize = vLogWriter.getFileSize();

vlogSequence = (int) (vLogFileSize / 8);

2. 按行读取文件

/**
 * InputStreamReader 按行读取25M内容约9319ms
 * @param path
 * @param results
 * @return
 */
public static  List<LocationBean>  test(String path, List<LocationBean> results ) {
    FileInputStream fis = null;
    BufferedReader br = null;
    try {
        File  file = new File(path);
         fis = new FileInputStream(file);
         br = new BufferedReader(new InputStreamReader(fis));

        String line = null;

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

            msgAction(line, results);
        }
       return results;
    }catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            fis.close();
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return null;
}

3. mmap不足如何在生成一个mmap映射文件

// 初始化一个mmap
public MmapLogWriter(File file) throws IOException {
  requireNonNull(file, "file is null");
  this.file = file;
  this.fileChannel = new RandomAccessFile(file, "rw").getChannel();
  //TODO append position should be file size mmap
  mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, PAGE_SIZE);
}

// 追加数据-》此缓冲区中剩余的元素数不足,就ummap重新再分配map
private void ensureCapacity(int bytes) throws IOException {
  // 此缓冲区中剩余的元素数不足,就ummap重新再分配map
  if (mappedByteBuffer.remaining() < bytes) {
    fileOffset += mappedByteBuffer.position();
    MMapUtil.unmap(mappedByteBuffer);
    mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, fileOffset, PAGE_SIZE);
  }
}

真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话

求点赞👍 求关注❤️ 求分享👥 对8块腹肌的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️