资讯专栏INFORMATION COLUMN

java io的一些总结

荆兆峰 / 1607人阅读

摘要:类的使用该类默认的写操作是覆盖操作。例如原来的文件内容是,我们将文件指针移向位置,即覆盖的位置在字符之后,我们写入个字符文件就变成了。具体思路是将目标文件分块,每个线程负责写入一个数据块。因此,全部线程执行完毕之后,文件的大小是。

RandomAccessFile类的使用

该类默认的写操作是覆盖操作。例如原来的文件内容是“abcde”,我们将文件指针移向2位置(seek(2),即覆盖的位置在b字符之后),我们写入3个字符:raf.write("xxx".getBytes());文件就变成了"abxxe"。如果我们要将xxx插入到b和c字符之间,默认的RandomAccessFile是无法实现的

/**
 * 向文本文件的特定位置插入字符串
 */
public static void insertStringToTxtFile(File f,String content,int pos) throws IOException{
    
    RandomAccessFile raf = new RandomAccessFile(f, "rw");
    raf.seek(pos);
    
    // 暂存插入点后的字符串
    byte[] buf = new byte[1024];
    int len = 0;
    StringBuilder sb = new StringBuilder();
    while ((len = raf.read(buf)) != -1) {
        sb.append(new String(buf, 0, len));
    }
    
    // 此时FP已经移动到了EOF,需要重新回到插入点写入字符串
    raf.seek(pos);
    raf.write(content.getBytes());
    raf.write(sb.toString().getBytes());
    raf.close();
    
}

以上的代码中最关键的代码是将文件指针之后的内容暂存起来,使用到了StringBuilder容器,读取的时候采用的是读取到字节数组(因为一次读取一行可能会产生换行的问题)。

该类用于随机读取文件,利用该类我们可以实现多线程写文件的操作。具体思路是将目标文件分块,每个线程负责写入一个数据块。例如:

public class WriteFile implements Runnable{

    private int block;                                // 数据块标号
    private File descFile;                            // 目标文件
    private static final int SIZE_PER_BLOCK = 20;    // 每个数据块大小
    
    public WriteFile(int block, File descFile) {
        super();
        this.block = block;
        this.descFile = descFile;
    }

    @Override
    public void run() {
        try {
            RandomAccessFile raf = new RandomAccessFile(descFile, "rw");
            raf.seek((block - 1) * SIZE_PER_BLOCK);
            raf.writeBytes("This is block " + block + "
");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
public class MultipleThreadWrite {
    
    static File file = new File("data.txt");
    
    public static void main(String[] args) {
        
        for (int i = 1; i < 6; i++) {
            new Thread(new WriteFile(i, file)).start();
        }
    }

}

以上开启了5个线程向data.txt文件中写入数据,每个线程负责写入一个数据块的数据,我们要写入的字符串的长度是16个字节,没有完全占用1个数据块,但是第二个线程写入数据的时候将文件指针移动到了20,从20开始写入,前面的4个字节是没有数据的。因此,全部线程执行完毕之后,文件的大小是 4 * 20 + 16 = 96bytes。

apache commons IO库

maven依赖如下:


    commons-io
    commons-io
    2.4

常用方法如下:

@Test
public void testFileUtils() throws Exception{
    
    File file = new File("test.txt");

    // 将文本文件读取为字符串
    String str = FileUtils.readFileToString(file, "utf-8");
    System.out.println("文本文件内容:" + str);
    
    // 文件大小
    System.out.println(FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(new File("F:/BaiduYunDownload/OS X Mavericks 10.9 (GM).iso"))));
    
    // 向文件中写入字符串
    FileUtils.writeStringToFile(new File("data.txt"), "你好hellodfd#$", "utf-8");
    
    // 遍历目录及其子目录下的所有文件
    Iterator iterator = FileUtils.iterateFilesAndDirs(new File("E:/tmp"), FileFileFilter.FILE, DirectoryFileFilter.DIRECTORY);
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
        
    }
    
    // 文件拷贝
    File destFile = new File("test_copy.txt");
    FileUtils.copyFile(file, destFile);
    
    // 从URL(必须是file协议,即本地计算机)中得到文件资源
    file = FileUtils.toFile(new URL("file:///E:/tmp/%E7%84%A6%E7%82%B9%E5%9B%BE.html"));
    System.out.println("本地文件:" + file);
    
    // 将文件拷贝到指定目录(目录不存在,创建之)
    FileUtils.copyFileToDirectory(file, new File("E:/tmp/demo"));
    
    // 拷贝一个目录(及其文件和子目录)到另一个目录
    FileUtils.copyDirectoryToDirectory(new File("E:/tmp"), new File("E:/demo"));
    
    // 下载远程资源到本地
    FileUtils.copyURLToFile(new URL("http://www.knowsky.com/384261.html"), new File("tmp.html"), 3000, 3000);
    
    // 删除目录中的内容
    FileUtils.deleteDirectory(new File("E:/demo"));
    
    // 移动文件(rename)
    FileUtils.moveFile(new File("test.txt"), new File("ok.txt"));
    
}

commons io参考文档

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64437.html

相关文章

  • 阿里之路+Java面经考点

    摘要:我的是忙碌的一年,从年初备战实习春招,年三十都在死磕源码,三月份经历了阿里五次面试,四月顺利收到实习。因为我心理很清楚,我的目标是阿里。所以在收到阿里之后的那晚,我重新规划了接下来的学习计划,将我的短期目标更新成拿下阿里转正。 我的2017是忙碌的一年,从年初备战实习春招,年三十都在死磕JDK源码,三月份经历了阿里五次面试,四月顺利收到实习offer。然后五月怀着忐忑的心情开始了蚂蚁金...

    姘搁『 评论0 收藏0
  • 少啰嗦!一分钟带你读懂JavaNIO和经典IO区别

    摘要:的选择器允许单个线程监视多个输入通道。一旦执行的线程已经超过读取代码中的某个数据片段,该线程就不会在数据中向后移动通常不会。 1、引言 很多初涉网络编程的程序员,在研究Java NIO(即异步IO)和经典IO(也就是常说的阻塞式IO)的API时,很快就会发现一个问题:我什么时候应该使用经典IO,什么时候应该使用NIO? 在本文中,将尝试用简明扼要的文字,阐明Java NIO和经典IO之...

    Meils 评论0 收藏0
  • Java知识点总结JavaIO-字节流)

    摘要:知识点总结字节流知识点总结字节流在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据时要使用输入流读取数据,而当程序需要将一些数据保存起来时,就要使用输出流。字节流主要操作类型数据,以数组为准,主要操作类是类和类。 Java知识点总结(JavaIO-字节流) @(Java知识点总结)[Java, JavaIO] [toc] 字节流 在程序中所有的数据都是以流的方式进行传输或保...

    BigTomato 评论0 收藏0
  • SegmentFault 技术周刊 Vol.40 - 2018,来学习一门新编程语言吧!

    摘要:入门,第一个这是一门很新的语言,年前后正式公布,算起来是比较年轻的编程语言了,更重要的是它是面向程序员的函数式编程语言,它的代码运行在之上。它通过编辑类工具,带来了先进的编辑体验,增强了语言服务。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不觉已经到来了,总结过去的 2017,相信小伙们一定有很多收获...

    caspar 评论0 收藏0
  • SegmentFault 技术周刊 Vol.40 - 2018,来学习一门新编程语言吧!

    摘要:入门,第一个这是一门很新的语言,年前后正式公布,算起来是比较年轻的编程语言了,更重要的是它是面向程序员的函数式编程语言,它的代码运行在之上。它通过编辑类工具,带来了先进的编辑体验,增强了语言服务。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不觉已经到来了,总结过去的 2017,相信小伙们一定有很多收获...

    nihao 评论0 收藏0

发表评论

0条评论

荆兆峰

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<