文件IO操作

 

文件转换成字节流,字节流为了加快速度(提供了缓冲区,一次性读多字节),再使用DataOutputStream使用固定的格式

 

 

 

 

 

 

字符有一个 readline() ,且对于中文的区别

 

1:如果只用FileOutputStream fileOutputStream = new FileOutputStream("d:/text.txt");
不是也能输出到"d:/text.txt"吗?为什么要用其它两个呢?能起到什么作用呢?
答案:
FileOutputStream :是字节流,它一个字节一个字节的向外边送数据
OutputStreamWriter:是字符流,它一个字符一个字符的向外边送数据
2:它们有什么区别么?
答案:
因为计算机是洋鬼子发明的,它们的英文字符占一个字节,而我们的中文是一个字符,至少占俩字节。
如果用stream,你读出来的英语再倒也罢了,读出来的中文可就是乱码或者一个个“????”。
如果你用WRITER,就不会有乱码了
3:BufferedWriter Buffer是一个缓冲区,为什么要用BUFFER呢?
答案:
如果你直接用stream或者writer,你的硬盘可能就是读一个字符或者一个字节 就去读写
硬盘一次,IO负担巨大。可是你用了Buffer,你的硬盘就是读了一堆数据之后,读写一下硬
盘。这样对你硬盘有好处。

 

RandomAccessFile

 

 

 

package classTop;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileTests {

private static final File file = new File("src\\testtxt\\raf.txt");
    
    /**
     * 向文件中写入内容
     */
    public static void testRandomAccessFileWriter() throws IOException{
        //要先将已有文件删除、避免干扰。
        if(file.exists()){
            file.delete();
        }
        
        RandomAccessFile rsfWriter = new RandomAccessFile(file, "rw");
        
        //不会改变文件大小、但是他会将下一个字符的写入位置标识为10000、
        //也就是说此后只要写入内容、就是从10001开始存、
        rsfWriter.seek(10000);
        printFileLength(rsfWriter);        //result: 0
        
        //会改变文件大小、只是把文件的size改变、
        //并没有改变下一个要写入的内容的位置、
        //这里注释掉是为了验证上面的seek方法的说明内容
        rsfWriter.setLength(10000);
        System.out.println("oo");
        printFileLength(rsfWriter);        //result: 0
        System.out.println("xx");
        //每个汉子占3个字节、写入字符串的时候会有一个记录写入字符串长度的两个字节
        rsfWriter.writeUTF("享学课堂");    
        printFileLength(rsfWriter);        //result: 10014 
        
        //每个字符占两个字节
        rsfWriter.writeChar('a');
        rsfWriter.writeChars("abcde");
        printFileLength(rsfWriter);        //result: 10026
        
        //再从“文件指针”为5000的地方插一个长度为100、内容全是'a'的字符数组
        //这里file长依然是10026、因为他是从“文件指针”为5000的地方覆盖后面
        //的200个字节、下标并没有超过文件长度
        rsfWriter.seek(5000);
        char[] cbuf = new char[100];
        for(int i=0; i<cbuf.length; i++){
            cbuf[i] = 'a';
            rsfWriter.writeChar(cbuf[i]);
        }
        
        
        printFileLength(rsfWriter);    //result:  10026
        
        //再从“文件指针”为1000的地方插入一个长度为100、内容全是a的字节数组
        //这里file长依然是10026、因为他是从“文件指针”为5000的地方覆盖后面
        //的200个字节、下标并没有超过文件长度
        byte[] bbuf = new byte[100];
        for (int i = 0; i < bbuf.length; i++) {
            bbuf[i] = 1;
        }
        rsfWriter.seek(1000);
        rsfWriter.writeBytes(new String(bbuf));
        printFileLength(rsfWriter);
    }
    
    /**
     * 从文件中读取内容
     * 这里我们要清楚现在文件中有什么内容、而且还要清楚这些内容起始字节下标、长度
     * 
     * @throws IOException
     */
    public static void testRandomAccessFileRead() throws IOException{
        /*
         * 对文件中内容简单说明:
         * 1、从0到1000    为空
         * 2、从1001到1100是100个1
         * 3、从1101到5000是空
         * 4、从5001到5200是字符'a'
         * 5、从5201到10000是空
         * 6、从10001到10011是字符串"陈华应"
         * 7、从10012到10023是"aabcde"
         */
        RandomAccessFile rsfReader = new RandomAccessFile(file, "r");
        //可按照自己想读取的东西所在的位置、长度来读取
        
  
        rsfReader.seek(10000);
        System.out.println(rsfReader.readUTF());
        
        //读取100个字符'a'
        rsfReader.seek(5000);
        byte[] bbuf = new byte[200];
        rsfReader.read(bbuf);
        System.out.println(new String(bbuf));
        
        //读取100个1
        byte[] bbuf2 = new byte[100];
        rsfReader.seek(1000);
        rsfReader.read(bbuf2, 0, 100);
        for(byte b : bbuf2){
            System.out.print(b);
        }
        
        //读取字符'aabcde'
        byte[] bbuf3 = new byte[12];
        rsfReader.seek(10014);
        rsfReader.read(bbuf3);
        System.out.println(new String(bbuf3));
    }
    /**
     * 打印文件长度
     * @param rsfWriter 指向文件的随机文件流
     * @throws IOException
     */
    private static void printFileLength(RandomAccessFile rsfWriter)
            throws IOException {
        System.out.println("file length: " + rsfWriter.length() + "  file pointer: " + rsfWriter.getFilePointer());
    }
    
    public static void main(String[] args) throws IOException {
        testRandomAccessFileWriter();
        testRandomAccessFileRead();
    }


}

 

==============================================================================================

 

package classTop;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.time.Duration;
import java.time.Instant;

public class FileChannelTest {
    
    public static void main(String[] args) {
        File sourceFile = new File("D://alvin//IOtest//file1.mp4");
        File targetFile = new File("D://file1-1.mp4");
        targetFile.deleteOnExit();
        try {
            targetFile.createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
        }

        copyFileByStream(sourceFile, targetFile);
        copyFileByFileChannel(sourceFile, targetFile);
    }
    
    private static void copyFileByFileChannel(File sourceFile,File targetFile){
        Instant begin = Instant.now();
        
        RandomAccessFile randomAccessSourceFile;
        RandomAccessFile randomAccessTargetFile;
        
        try {
            randomAccessSourceFile = new RandomAccessFile(sourceFile, "r");
            randomAccessTargetFile = new RandomAccessFile(targetFile, "rw");
            
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        
        FileChannel sourceFileChannel = randomAccessSourceFile.getChannel();
        FileChannel targetFileChannel = randomAccessTargetFile.getChannel();
        
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024*1024);
        try {
            while(sourceFileChannel.read(byteBuffer) != -1) {//读一串数据
                byteBuffer.flip();                                      //回到开头
                targetFileChannel.write(byteBuffer);     //写
                byteBuffer.clear();                                  //清空
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                sourceFileChannel.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            
            try {
                targetFileChannel.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("total spent: " + Duration.between(begin, Instant.now()).toMillis());
    }
    
    private static void copyFileByStream(File sourceFile,File targetFile) {
        Instant begin = Instant.now();
        
        FileInputStream fis;
        FileOutputStream fos;
        
        try {
            fis = new FileInputStream(sourceFile);
            fos = new FileOutputStream(targetFile);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return;
        }
        byte[] readed = new byte[1024*1024];
        try {
            while (fis.read(readed) != -1) {
                fos.write(readed);
            }
        } catch( IOException e){
            e.printStackTrace();
        } finally {
            try{
                fos.close();
            }catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
            try {
                fis.close();
            } catch (Exception e2) {
                // TODO: handle exception
                e2.printStackTrace();
            }
        }
        System.out.println("total spent: " + Duration.between(begin, Instant.now()).toMillis());
        
    }

}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值