RandomAccessFile

本文详细介绍了RandomAccessFile的特点和使用方法,重点讲解了在不同情况下如何避免乱码问题,包括write(String.getBytes())方法的正确使用。并通过两个案例演示了如何利用多线程进行文件的高效读写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.youkuaiyun.com/detail/bobo8945510/9667130

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值