RandomAccessFile

来源:互联网 发布:淘宝店铺过户近亲属 编辑:程序博客网 时间:2024/04/23 21:53

RandomAccessFile特点

1、只能访问文件,不能操作其他io设备
2、支持随机访问
3、在读写等长记录文件有优势

RandomAccessFile请注意乱码问题:

使用write(String.getBytes()), 能够正常写入
使用writeBytes(String), writeChars(String), writeUTF(String)均产生乱码。

1、String.getBytes()将会按照当前系统默认的encoding方式获得字符串的 Bytes,RandomAccessFile.write(byte[])将这个byte数组正确写入。由于写入的实际就是Windows平台的 nativecode编码,所以文件还能够被正确的阅读。

2、RandomAccessFile.writeBytes(String)将字符串的各个字符(当然是用unicode编码的)的高8位去掉,写入文件。

3、RandomAccessFile.writeChars(String)将字符串的各个字符按照unicode的编码,以Big-endian的方 式写入文件。Windows平台上默认文件的编码方式为Little-endian,所以用写字板打开看到的是乱码,但是如果我们用浏览器打开这个文件 (testWriteChars.dat)并指定编码方式为Unicode Big-endian,就能看到正常的“中”字了。

4、RandomAccessFile.writeUTF(String)首先写入00 03表示其后将写入3个实际的字节,然后写入“中”的UTF-8编码:E4 B8 AD

RandomAccessFile案例一:

写一个线程,来接受主类传递过来的file,然后进行处理。这里使用的是使用write(String.getBytes()),不会有乱码

import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.RandomAccessFile;public class RandomThere02 extends Thread{    /*     *      *使用RandomAccessFile向数据库写入中文的时候,     *使用write(String.getBytes()), 能够正常写入     *使用writeBytes(String), writeChars(String), writeUTF(String)均产生乱码。     * */    File  files;    int modules = 1;//  int num = 10;    public RandomThere02(File file,int m) {        files = file;        modules = m;    }    @Override    public void run() {        try {            RandomAccessFile rA = new RandomAccessFile(files,"rw");            String ss = "我是一只鱼---+\r\n";            //根据ss内容来计算指针的位置            rA.seek((modules-1)*ss.getBytes().length);            rA.write(ss.getBytes("gb2312"));            rA.close();         } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

主类代码

import java.io.File;public class RandomAccessFileText02 {    /*     * RandomAccessFile随机文件读写     * */    static File file = new File("d://data//newhello.txt");    public static void main(String[] args) {        if(file.exists()){            file.delete();        }else {            System.out.println("dadfasfafsadf好烦啊");            new RandomThere02(file, 1).start();            new RandomThere02(file, 2).start();            new RandomThere02(file, 3).start();            new RandomThere02(file, 4).start();            new RandomThere02(file, 5).start();        }           }}

结果:

这里写图片描述


RandomAccessFile案例二,实现多线程下载文件,并复制成一个新文件:

写一个线程,

import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.RandomAccessFile;public class RandomThere01 implements Runnable{    /*     *      *使用RandomAccessFile向数据库写入中文的时候,     *使用write(String.getBytes()), 能够正常写入     *使用writeBytes(String), writeChars(String), writeUTF(String)均产生乱码。     * */    private String source;      private String dest;      private int buflen=1024*1024;      private int threadnum;//定义线程个数      private Thread thread[];//定义线程数组     public RandomThere01(String source,String dest)      {          this.source=source;           this.dest=dest;      }      public RandomThere01(String source,String dest,int threadnum)      {          this.source=source;          this.dest=dest;          this.threadnum=threadnum;      }      public void getThread()      {          thread = new Thread[threadnum];          for(int i=0;i<thread.length;i++)              {                  thread[i]=new Thread(this);                  thread[i].setName(i+"");//设置线程的名字,用于区分其他线程              }      }      public void run()      {          int id=Integer.valueOf(Thread.currentThread().getName());          byte buffer[] = new byte [buflen];          try {               RandomAccessFile reader=new RandomAccessFile(source,"r");//为每个线程定义一个读取的对象              RandomAccessFile writer= new RandomAccessFile(dest,"rw");               long alone=reader.length()%threadnum==0?reader.length()/threadnum:((int)(Math.ceil((double)reader.length()/threadnum)));//计算每个线程应该读取的长度               long begin=id*alone;   //第个线程读取文件的开始位置               reader.seek(begin);//定位到开始位置               writer.seek(begin);               long end=(begin+alone)>reader.length()?reader.length():(begin+alone);//计算每个线程的结束位置               while(begin<end)               {                   int len=0;                   if(begin+buflen<end)//如果可以装满一个缓冲区                   {                       len=reader.read(buffer);                   }else                   {                       len=reader.read(buffer,0,(int)(end-begin));                   }                   writer.write(buffer,0,len);                    begin+=len;                   System.out.println("Thread-"+id+"get "+len);               }          }catch(Exception ex)          {              System.out.println(ex);          }      }      public int getThreadNumber()      {          return this.thread.length;      }      public void start()      {          for(int i=0;i<thread.length;i++)              thread[i].start();      }     }

主类代码

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;public class RandomAccessFileText01 {    public static void main(String[] args) throws Exception {          // 第一个参数,你的源文件,第二个参数:你需要复制的位置,第三个文件:开启多少个线程         long begin=System.currentTimeMillis();         RandomThere01 load = new RandomThere01("d:\\abc.txt","D:\\abc_new.txt",5);         //调用getThread()方法为每一个线程赋值,用于计算偏移量        load.getThread();         //开启线程进行数据下载        load.start();         //当完成下载我们计算一下我们所有的耗时        while(true)         {             if(Thread.activeCount()==1)                 {                 long end=System.currentTimeMillis();                 System.out.println("多线程:Download successfully..."+(end-begin)+"ms");                 break;                 }         }       System.out.println("开始");    }  }

运行结果:成功

这里写图片描述


demo地址:http://download.csdn.net/detail/bobo8945510/9667130

0 0
原创粉丝点击