`
canyue_2007
  • 浏览: 5469 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
文章分类
社区版块
存档分类
最新评论

用MappedByteBuffer进行特大文件拷贝分割

阅读更多
目的:
    有时候用U盘转移大文件时,U盘空间太小,想写一个小程序能把文件分割方便转移。

问题一:用Buffer直接将文件(1G以上)映入内存,不可能直接进物理内存。
    解决方案:将文件用Map映射到一个MappedByteBuffer中

问题二:报告“java.io.IOException: 存储空间不足,无法处理此命令。”异常。
    解决方案:将文件分段映射。注意文件较大时必须显式调用
              System.gc();
            System.runFinalization();
            否则还是可能报上述异常。
        原因:《JAVA编程思想》4.3 清除:收尾和垃圾收集  有如下说明:
              当然,Java可用垃圾收集器回收由不再使用的对象占据的内存。现在考虑
              一种非常特殊且不多见的情况。假定我们的对象分配了一个“特殊”内存区
              域,没有使用new。垃圾收集器只知道释放那些由new分配的内存,所以不知
              道如何释放对象的“特殊”内存。为解决这个问题,Java提供了一个名为
              finalize()的方法,可为我们的类定义它。

问题三:原文件不可被删除(在程序退出之前)。
    解决方案:JDK API 1.60中有“映射的字节缓冲区和它所表示的文件映射关系在该缓冲
              区本身成为垃圾回收缓冲区之前一直保持有效。 ”关于此问题众说纷纭,并
              且在sun.bug中也在讨论。笔者认为只要最后把映射指向一个无关的文件即可
              解决。

关键代码:
              frame.jTextField6.getText()  //待分割的文件
              frame.jTextField5.getText()+"\\"+this.findname() //保存位置
              findex   //方便以后组合

try{
            File fcut = new File(frame.jTextField6.getText());
            File fsave = new File(frame.jTextField5.getText()+"\\"+this.findname());
            if(!fsave.exists()){
                fsave.mkdir();
            }
            File findex = new File(frame.jTextField5.getText()+"\\"+this.findname()+"\\cut.index");
            FileWriter fw = new FileWriter(findex);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(this.findname()+"."+this.findkuozhan(),0,(this.findname()+"."+this.findkuozhan()).length());
            bw.newLine();

            int num = size_i;  //分割份数
            long totalsize = fcut.length();   //文件总大小
            long persize = totalsize/num;     //每个大小

            FileInputStream fis = new FileInputStream(fcut);
            FileChannel fic = fis.getChannel();

            if(persize>buffersize){
                for(int i=0;i<num;i++){
                    RandomAccessFile ras = new RandomAccessFile(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1),"rw");
                    FileChannel frs = ras.getChannel();
                    if(i<num-1){
                        for (int j = 0; j < persize / buffersize; j++) {
                            if (j < persize / buffersize - 1) {
                                MappedByteBuffer mibb = fic.map(FileChannel.MapMode.READ_ONLY,i * persize + j * buffersize,buffersize);
                                MappedByteBuffer mobb = frs.map(FileChannel.MapMode.READ_WRITE,j*buffersize,buffersize);
                                mobb.put(mibb);
                                mibb.clear();
                                mobb.clear();
                            }else{
                                MappedByteBuffer mibb = fic.map(FileChannel.MapMode.READ_ONLY,i * persize + j * buffersize,buffersize+persize%buffersize);
                                MappedByteBuffer mobb = frs.map(FileChannel.MapMode.READ_WRITE,j*buffersize,buffersize+persize%buffersize);
                                mobb.put(mibb);
                                mibb.clear();
                                mobb.clear();
                            }
                        }
                        System.gc();
                        System.runFinalization();
                        bw.write(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1),0,(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1)).length());
                        bw.newLine();
                    }else{
                        for (int j = 0; j < persize / buffersize; j++) {
                            if (j < persize / buffersize - 1) {
                                MappedByteBuffer mibb = fic.map(FileChannel.MapMode.READ_ONLY,i * persize + j * buffersize,buffersize);
                                MappedByteBuffer mobb = frs.map(FileChannel.MapMode.READ_WRITE,j*buffersize,buffersize);
                                mobb.put(mibb);
                                mibb.clear();
                                mobb.clear();
                            }else{
                                MappedByteBuffer mibb = fic.map(FileChannel.MapMode.READ_ONLY,i * persize + j * buffersize,totalsize-(i * persize + j * buffersize));
                                MappedByteBuffer mobb = frs.map(FileChannel.MapMode.READ_WRITE,j*buffersize,totalsize-(i * persize + j * buffersize));
                                mobb.put(mibb);
                                mibb.clear();
                                mobb.clear();
                            }
                        }
                        System.gc();
                        System.runFinalization();
                        bw.write(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1),0,(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1)).length());
                        bw.close();
                        fw.close();
                    }
                    ras.close();
                    frs.close();
                }
                fis.close();
                fic.close();

            }else{
                for(int i=0;i<num;i++){
                    RandomAccessFile ras = new RandomAccessFile(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1),"rw");
                    FileChannel frs = ras.getChannel();
                    if(i<num-1){

                        MappedByteBuffer mibb = fic.map(FileChannel.MapMode.READ_ONLY,i * persize,persize);
                        MappedByteBuffer mobb = frs.map(FileChannel.MapMode.READ_WRITE,0,persize);
                        mobb.put(mibb);
                        mibb.clear();
                        mobb.clear();

                        System.gc();
                        System.runFinalization();
                        bw.write(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1),0,(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1)).length());
                        bw.newLine();
                    }else{

                        MappedByteBuffer mibb = fic.map(FileChannel.MapMode.READ_ONLY,i * persize,totalsize-i * persize);
                        MappedByteBuffer mobb = frs.map(FileChannel.MapMode.READ_WRITE,0,totalsize-i * persize);
                        mobb.put(mibb);
                        mibb.clear();
                        mobb.clear();

                        System.gc();
                        System.runFinalization();
                        bw.write(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1),0,(frame.jTextField5.getText()+"\\"+this.findname()+"\\"+this.findname()+".cut"+(i+1)).length());
                        bw.close();
                        fw.close();
                    }
                    ras.close();
                    frs.close();
                }
                fis.close();
                fic.close();


            }
        jop = new JOptionPane();
        jop.showMessageDialog(frame.getContentPane(),"文件分割完毕!", "成功", JOptionPane.ERROR_MESSAGE);
        }catch(Exception e){
            jop = new JOptionPane();
            jop.showMessageDialog(frame.getContentPane(),e.toString(), "错误", JOptionPane.ERROR_MESSAGE);
        }
分享到:
评论

相关推荐

    文件分割和合并(您的文件大的不能传输怎么办?)

    本人初学c++,写了一个小软件,能把大文件分割问小文件,然后可以统国网络传输,到了网络另一端,再用此软件拼接! 希望用过的人能提宝贵意见! 13521825644 qq 362192302

    深入浅出MappedByteBuffer.pdf

    深入浅出MappedByteBuffer

    读取文件数据并解析成bean实体类

    很多时候需要文件做数据交互,接收到文件后需要对文件解析成bean实体类,这里提供的是工具类,任意文件转任意实体都可以,只要简单的配置一下Class类,很实用

    Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer

    Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer

    j2se项目源码及介绍_last指令

    在今后的电信用户数据采集系统项目中,就是通过读取该系统文件来确定用户使用电信实验室服务器的时间长度并收费的。 该系统文件的目录与文件名是/usr/adm/wtmpx,在Unix的系统提供一组的核函数来操作该函数,相对...

    Android渠道打包工具packer-ng-plugin.zip

    }读取ZIP文件注释,有两个版本的实现,这里使用的是 RandomAccessFile ,另一个版本使用的是 MappedByteBuffer ,经过测试,对于特别长的注释,使用内存映射文件读取性能要稍微好一些,对于特别短的注释(比如渠道名...

    mmf4j:MemoryMappedFiles4Java

    与已经存在的MappedByteBuffer相比,目标是更好地控制创建,修改和销毁。 它试图统一在不同操作系统上使用此类映射的接口,这意味着许多细节无法实现。 此外,在某些情况下,您可能需要完成目标平台上可能不需要的...

    mmfinvoker:简单的进程间 java 请求-响应库

    mmfinvoker 这是一个简单的 java 库,它使用 nio.MappedByteBuffer 在内存映射文件上实现请求/响应功能。

    ip地址库 很全的库

    Log4jUtil.error("IP地址信息文件格式有错误,IP显示功能将无法使用", e); ipFile = null; } } } /** * @return 单一实例 */ public static IPSeeker getInstance(String wryIPURL) {...

    jdk-14_linux-x64_bin.rpm

    非易失性映射的字节缓冲将添加新的 JDK 特定文件映射模式,该模式允许 FileChannel API 用于创建引用非易失性内存(NVM)的 MappedByteBuffer 实例。 358:Helpful NullPointerExceptions 改进 ...

    百度地图开发java源码-inertiaSearch:挑战赛

    百度地图开发java源码 tmp #inertiaSearch 2016年写的代码,现在觉得思路有很多提升的地方,但是毕竟...项目大量的使用了nio中的mmap(MappedByteBuffer) 对于原始的数据文件做内存映射,并做对应索引,所有索引做hash

    【密码:5261】Oracle官网下载64位-JDK14

    jdk14新特性:改进NullPointerExceptions,通过准确描述哪些变量为null...非易失性映射的字节缓冲将添加新的JDK特定文件映射模式,该模式允许FileChannel API用于创建引用非易失性内存(NVM)的MappedByteBuffer实例。

    commons-mmf.rar_java nio_java共享内存_共享内存

    java的共享内存管理.基于MMF设计。封装了java.nio.MappedByteBuffer.在大流量实时业务系统时,可以极大的提高处理效率

    CsvReader:CsvReader

    CsvReader CsvReader -&gt; I am using BufferedReader for its fast enough for a sequential access upto 100MB of data, ...我无法在symbol.txt上进行验证。 单元测试:我找不到足够的时间来运行所有单元测试

    sambox:一个PDFBox分支,打算用作Sejda和PDFsam的PDF处理程序

    SAMBox使用允许使用基于java.nio.channels.FileChannel , java.io.InputStream和java.nio.MappedByteBuffer的提供的实现之一(是否缓冲)。 通过使用java.lang.StringBuilder池最小化GC。 通过绑定视图的概念直接...

    Android代码-BitMap

    a pratise of bigdata sorting,use some common util or class,like File,FileOutputStream,RandomAccessFile,HashMap,BufferedOutputStream,ByteBuffer,MappedByteBuffer,FileInputStream. as a newer of ...

    txt文档阅读器

    //MappedByteBuffer 将文件直接映射到内存 private int m_mbBufLen = 0; private int m_mbBufBegin = 0; private int m_mbBufEnd = 0; private String m_strCharsetName = "gbk";//文本格式 private Bitmap m_...

    javaredis源码-jredis-master:java实现redis

    RAM中仅使用键,该值是延迟加载 逐出政策 LRU algorithm 线性存储 1.based on jdk's MappedByteBuffer 2.fixed unit size ,head 4 byte write in last item position, and then each item write in 4 byte with i

    java8源码-netty-learn:这是一个用于netty学习的工程

    (用于TCP网络编程,客户端和服务器端都能用) ServerSocketChannel (用于TCP网络编程,专用与服务器端) 常见的Buffer,用来缓冲读写数据。 ByteBuffer MappedByteBuffer DirectByteBuffer HeapByteBuffer ...

Global site tag (gtag.js) - Google Analytics