文件读写

2018-07-06  本文已影响0人  luoqiang108

RandomAccessFile

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
/**
 * RandomAccessFile读写文件。
 */
public class RandomAccessFileTest {
    public static void main(String[] args) {
        try {
            /**
             * 向文件.\data.dat中写数据
             * 步骤:
             * 1、创建一个File对象用于描述该文件
             * 2、不存在则创建该文件
             * 3、创建RandomAccessFile,并将File传入。
             * 使RandomAccessFile对File表示的文件进行
             * 读写操作
             * 4、向文件中写入内容
             */
            //1
            File file = new File("data.dat");
            //2、不存在则创建该文件
            if (!file.exists()) {
                file.createNewFile();
            }
            //3、对file文件可以进行读写操作
            RandomAccessFile raf =new RandomAccessFile(file,"rw");
            //4、写一个int最大值
            /**
             * 2位16进制代表一个字节(8位2进制)
             * 1位16进制代表4位2进制 f==1111
             * 4字节代表32位2进制
             *
             * write(int)写一个字节
             *    7f       ff       ff       ff
             * 01111111 11111111 11111111 11111111
             *
             * 00000000 00000000 00000000 01111111 00 00 00 7f
             * 00000000 00000000 01111111 11111111 00 00 7f ff
             * 00000000 01111111 11111111 11111111 00 7f ff ff
             * 01111111 11111111 11111111 11111111 7f ff ff ff
             */
            int i = 0x7fffffff;//int最大值
            //写int值最高的8位
            raf.write(i>>>24);//00 00 00 7f
            raf.write(i>>>16);//00 00 7f ff
            raf.write(i>>>8);//00 7f ff ff
            raf.write(i);    //7f ff ff ff
            //定义一个10字节数组
            byte[] data = new byte[]{0,1,2,3,4,5,6,7,8,9};
            //将这10个字节全部写入文件
            raf.write(data);
            //写到这里,当前文件应该有14(前面int的4字节加后面数字的10字节)个字节了
            /**
             * 写字节数组的重载方法
             *write(byte[] data,int offset,int length)
             * 从data数组的offset位置开始写,连续写length个字节到文件中。
             */
            raf.write(data,2,5);//{2,3,4,5,6}
            System.out.println("当前指针位置:"+raf.getFilePointer());//19
            raf.seek(0);//将指针移动到文件开始的位置
            System.out.println("当前指针位置:"+raf.getFilePointer());//0
            /**
             * num:00000000 00000000 00000000 00000000
             */
            int num = 0;//准备读取的int值
            int b = raf.read();//读取第一个字节 7f
            System.out.println("当前指针位置:"+raf.getFilePointer());//1
            num = num|(b<<24);//01111111 00000000 00000000 00000000
            b = raf.read();//读取第二个字节 ff
            num = num|(b<<16);//01111111 11111111 00000000 00000000
            b = raf.read();//读取第三个字节 ff
            num = num|(b<<8);//01111111 11111111 11111111 00000000
            b = raf.read();//读取第四个字节 ff
            num = num|b;//01111111 11111111 11111111 11111111
            System.out.println("int最大值"+num);//int最大值2147483647
            raf.seek(0);
            byte[] buf = new byte[1024];//1k的容量
            int sum = raf.read(buf);//尝试读取1k的数据
            System.out.println("总共读取了"+sum+"个字节");
            System.out.println(Arrays.toString(buf));
            /*RandomAccessFile的其他读写*/
            raf.seek(0);
            //写int最大值
            raf.writeInt(Integer.MAX_VALUE);//一次写4个字节,写int值
            //写long最大值
            raf.writeLong(Long.MAX_VALUE);
            //写字符串
            raf.writeUTF("hello!");
            raf.seek(0);
            int intMax = raf.readInt();//连续读取4字节返回该int值
            long longMax = raf.readLong();
            String string = raf.readUTF();
            raf.close();//写完了不再写了就关了
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

java I/O 输入/输出

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class FISFOSTest {
    public static void main(String[] args) throws IOException {
        File file = new File("data.dat");
        /**
         * 根据文件创建用于读取其数据的文件输入流
         */
        FileInputStream fis = new FileInputStream(file);
        int b = -1;
        while ((b=fis.read())!=-1){
            //输出这个字节的16进制形式
            System.out.print(Integer.toHexString(b));
        }
        fis.close();//切记,流用完了要关闭!
        /*
        * 文件输入流FileOutputStream
        * write(int d):写int值的低八位
        * write(byte[] d):将d数组中所以字节写出
        * write(byte[] d,int offset,int length):将d数组中offset位置开始
        * 写length个字节
        * */
        File outFile =new File("out.txt");
        if (!outFile.exists()){
            file.createNewFile();
        }
        //FileOutputStream fos = new FileOutputStream(outFile);
        /*
        * FileOutputStream(File file,boolean append)
        * append为true:会在当前文件末尾进行写操作
        * FileOutputStream(String filePath,boolean append)
        * 传文件路径进行写入
        * */
        FileOutputStream fos = new FileOutputStream(outFile,true);
        String info = "你好!输出流!";
        byte[] outData = info.getBytes("UTF-8");
        fos.write(outData);//将字符串转换的字节写出
        fos.close();



        //测试IO工具类方法
        byte[] data =IOUtils.loadBytes(new File("data.dat"));
        System.out.print("\n"+Arrays.toString(data));
        File des = new File("abc.dat");//该文件在磁盘上不存在
        IOUtils.saveBytes(des,data);
        File srcCopy = new File("Eclipse.zip");
        File desCopy = new File("EclipseCopy.zip");
        //IOUtils.copyFile(srcCopy,desCopy);
        //IOUtils.copyFile2(srcCopy,desCopy);
        //测试DataOutputStream
        FileOutputStream out = new FileOutputStream("o.txt");
        IOUtils.saveString("大家好才是真的好!",out);
        out.close();
        FileInputStream in = new FileInputStream("o.txt");
        System.out.println("\n"+IOUtils.loadString(in));
    }
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * IO工具类
 */

public class IOUtils {
    /**
     * 读取给定的文件,并将数据以字节数组的形式返回
     * @param src
     * @return
     */
    public static byte[] loadBytes(File src) throws IOException{
        if (src==null){
            throw new IllegalArgumentException("文件为空!");
        }
        if (!src.exists()){
            throw new IllegalArgumentException(src+"不存在!");
        }
        FileInputStream fis = null;//创建文件输入流
        try{
            fis = new FileInputStream(src);
            /*FileInputStream的available()方法:
            * 返回当前字节输入流可读取的总字节数
            * */
            byte[] data = new byte[fis.available()];
            fis.read(data);
            return data;
        }catch (IOException e){
            throw e;//读取出现错误将异常抛给调用者解决
        }finally {
            if (fis!=null){
                fis.close();
            }
        }
    }

    /**
     * 数据源 DataSource
     * 将给定数组写入给定文件中
     * @param src
     * @param data
     * @throws IOException
     */
    public static void saveBytes(File src ,byte[] data) throws IOException{
        if (src==null){
            throw new IllegalArgumentException("文件为空!");
        }
        //FileOutputStream(File file),若file文件不存在FileOutputStream(File file)构造方法会自动创建该文件
        /*if (!src.exists()){
            src.createNewFile();
        }*/
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(src);
            fos.write(data);
        }catch (IOException e){
            throw e;
        }finally {
            if (fos!=null){
                fos.close();
            }
        }
    }

    /**
     * 将文件复制保存到des文件
     * @param src
     * @param des
     * @throws IOException
     */
    public static void copyFile(File src,File des) throws IOException{
        if (src==null){
            throw new IllegalArgumentException("源文件为空!");
        }
        if (!src.exists()){
            throw new IllegalArgumentException("源文件不存在!");
        }
        if (des==null){
            throw new IllegalArgumentException("目标文件为空!");
        }
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(src);
            fos = new FileOutputStream(des);
            int data = -1;
            while ((data=fis.read())!=-1){
                fos.write(data);
            }
            /*byte[] srcData = new byte[fis.available()];
            fis.read(srcData);
            fos.write(srcData);*/
        }catch (IOException e){
            throw e;
        }finally {
            if (fis!=null){
                fis.close();
            }
            if (fos!=null){
                fos.close();
            }
        }
    }

    /**
     * 使用缓冲流进行文件拷贝
     * @param src
     * @param des
     */
    public static void copyFile2(File src,File des) throws IOException{
        if (src==null){
            throw new IllegalArgumentException("源文件为空");
        }
        if (!src.exists()){
            throw new IllegalArgumentException("源文件不存在");
        }
        //创建缓冲流
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(src));
            bos = new BufferedOutputStream(new FileOutputStream(des));
            int data = -1;
            while ((data=bis.read())!=-1){
                bos.write(data);
            }
            /*flush的作用是将缓冲区中未写出的数据一次性写出*/
            bos.flush();//数据都写完后应该flush
        }catch (IOException e){
            throw e;
        }finally {
            if (bis!=null){
                /*通常情况下,我们只需要关闭最外层的流,里层的流会自动关闭*/
                bis.close();
            }
            if (bos!=null){
                bos.close();
            }
        }
    }

    /**
     * 向给定的输出流中写字符串
     * @param info
     * @param out
     * @throws IOException
     */
    public static void saveString(String info, OutputStream out)throws IOException{
        /*
        * 步骤:
        * 1:创建DataOutputStream并处理参数out这个输出流
        * 2:通过DOS直接将一个字符串写出
        * 3:清空DOS的缓冲区,确保所有字符都写出。
        * */
        //1
        DataOutputStream dos = new DataOutputStream(out);
        //2
        dos.writeUTF(info);//将字符串写出
        //3
        dos.flush();//将缓冲区中的数据写出
        //这里应该将dos关掉么?
        /*不需要关,因为关闭会连带自动的把传递进来的out低级流关闭,
        而这个低级流传参处很可能还需要用,这里dos在方法里用完后,
        其它地方没有对它的应用,GC会自动把它回收*/
    }

    /**
     * 从输入流中读取字符串
     * @param in
     * @return
     * @throws IOException
     */
    public static String loadString(InputStream in)throws IOException{
        DataInputStream dis = new DataInputStream(in);
        String data = dis.readUTF();
        return data;
    }
}

字符流:

以字符为单位读写数据,一次处理一个字符(unicode)。字符流底层还是基于字节形式读写的。所有字符流都是高级流。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;

/**
 * Created by 罗强 on 2018/7/9.
 */

public class CharacterStreamTest {
    public static void main(String[] args) throws IOException {
        /*字符输出流
        * Writer:字符输出流
        * OutputStreamWriter:高级流,可以以字符为单位写数据
        * */
        /*向文件中写入字符
        * 步骤
        * 1:创建文件输出流(字节流)
        * 2:创建字符输出流(高级流),处理文件输出流
        * 目的是我们可以以字节为单位写数据
        * 3:写入字符
        * 4写完后关闭流*/
        OutputStreamWriter writer = null;
        try {
            //1
            FileOutputStream fos =new FileOutputStream("writer.txt");
            //2
            //writer = new OutputStreamWriter(fos);//使用系统默认编码集输出字符串
            //使用UTF-8作为编码集输出字符串
            writer = new OutputStreamWriter(fos,"UTF-8");
            //3
            writer.write("你好!");
            writer.flush();//将缓冲区数据一次性写出
        }catch (IOException e){
            throw e;
        }finally {
            //4
            if (writer!=null){
                writer.close();
            }
        }
        /**
         * 字符输入流
         */
        InputStreamReader reader = null;
        try {
            //创建用于读取文件的字节输入流
            FileInputStream fis = new FileInputStream("writer.txt");
            //创建用于以字符为单位的读取数据的高级流
            reader = new InputStreamReader(fis);
            //读取数据
            int c = -1;
            while ((c=reader.read())!=-1){
                System.out.println((char)c);
            }
        }catch (IOException e){
            throw e;
        }finally {
            if (reader!=null){
                reader.close();
            }
        }

        /*缓冲字符输出流
        * 高级流
        * 可以以行为单位写字符
        * */
        //创建用于写文件的输出流
        FileOutputStream fos = new FileOutputStream("buffered.txt");
        //创建一个字符输出流
        OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
        /*
        BufferedWriter的构造方法中不支持给定一个字节输出流
        只能给定一个字符输出流Writer的子类
        Writer:字符输出流的父类
         */
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write("你好呀!");
        bw.newLine();//输出一个换行
        bw.write("我是第二行");
        bw.newLine();
        bw.write("我是第三行");
        //输出流关闭后,不能再通过其写数据
        bw.close();
        /*
        * 缓冲字符输入流
        * 读取src/day02/DemoBufferedReader.java
        * readLine()
        * */
        FileInputStream fis = new FileInputStream("src"+ File.separator+
                "day02"+File.separator+"DemoBufferedReader.java");
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        String str =null;
        /**
         * readLine()读取一行字符并以字符串形式返回
         * 返回值中不带换行符。
         * 若返回null,说明读取到了文件末尾
         * EOF:end of file 文件末尾
         */
        while ((str=br.readLine())!=null){
            System.out.println(str);
        }
        reader.close();

        //打印字节流
        System.out.println("你好!");
        PrintStream out = System.out;
        PrintStream fileOut =
                new PrintStream(new FileOutputStream("SystemOUT.TXT"));
        //将我们指定的输出流赋值到System.out上
        System.setOut(fileOut);
        System.out.println("你好!我是输出到控制台的!");
        System.setOut(out);
        System.out.println("我是输出到控制台的!");
        fileOut.close();
    }
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Created by 罗强 on 2018/7/11.
 */

public class FileWriterAndFileReaderTest {
    public static void main(String[] args) throws IOException{
        //文件字符输出流
        /*常用的两个构造方法
        * FileWriter(File file)
        * FileWriter(String filePath)
        * 意思和FileOutputStream的两个同类型参数的构造方法一致
        *
        * FileWriter的效果等同于
        * FileOuputStream + OutputStreamWriter
        * */
        FileWriter writer = new FileWriter("filewriter.txt");
        //File file = new File("filewriter.txt");
        //writer = new FileWriter(file);
        writer.write("hello!FileWriter!");
        writer.close();
        //文件字符输入流
        FileReader reader = new FileReader("filewriter.txt");
        int c = -1;
        //以字符为单位读取文件
        while ((c=reader.read())!=-1){
            System.out.print((char)c);
        }
        // 文件字符输入流转换为缓冲字符输入流便可以以行为单位读取
        BufferedReader br = new BufferedReader(reader);
        String info = null;
        while ((info=br.readLine())!=null){
            System.out.println(info);
        }
        reader.close();
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class PrintWriterTest {
    public static void main(String[] args) throws IOException{
        PrintWriter writer =new PrintWriter("printwriter.txt");
        //向文件写入一个字符串
        writer.println("你好!PrintWriter");//自动加换行符;
        /*
        * 我们要在确定做写操作的时候调用flush()方法
        * 否则数据可能会在输出流的缓冲区中,没有做真实的写操作!
        * */
        writer.flush();
        writer.close();
        /*使用缓冲字符输入流读取键盘输入信息*/
        /*
        * 将键盘的输入流转换为字符输入流在转换为缓冲字符输入流
        * */
        //1、将键盘的字节输入流转换为字符输入流
        InputStreamReader isr = new InputStreamReader(System.in);
        //2、将字符输入流转换为缓冲字符输入流。按行读取信息
        BufferedReader br = new BufferedReader(isr);
        //循环读取用户输入信息并输出到控制台
        while (true){
            String info = br.readLine();
            if ("exit".equals(info)){
                break;
            }
            /*
            * 若我们不是输出到控制台,而是通过对文件的输出流
            * 进行写操作,可以将控制台的信息写到文本文件中了。
            * */
            System.out.print(info);
        }
        br.close();
    }
}

断点续传

import java.io.Serializable;

/**
 * 保存一个下载任务所需要的信息
 * VO:Value Object 值对象
 * 作用:保存一组数据。
 * 若这组数据表示的是数据库中的一条数据的话
 * 那么这个对象就叫做:Entity实体
 */

public class DownloadInfo implements Serializable {
    private String url;//下载文件的地址
    private long pos;//已经下载的字节数
    private long fileSize;//文件总大小
    private String fileName;//保存在本地的文件名

    public DownloadInfo(String url, String fileName) {
        this.url = url;
        this.fileName = fileName;
    }

    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }

    public long getPos() {
        return pos;
    }
    public void setPos(long pos) {
        this.pos = pos;
    }

    public long getFileSize() {
        return fileSize;
    }
    public void setFileSize(long fileSize) {
        this.fileSize = fileSize;
    }

    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 断点续传测试
 */

public class TestHttpDownload {
    public static void main(String[] args){
        /*
        * 1:创建下载任务DownLoadInfo实例
        * 2:根据任务中的下载地址打开网络连接,获取对应输入流
        * 3:创建任务中保存在本地的文件的输出流
        * 4:进行读写操作(下载)
        * 5:关闭流
        * */
        try {
            //1
            DownloadInfo info = new DownloadInfo("http://www.baidu.com/download/java_1_7.zip",
                    "java_1_7.zip");
            //2
            URL url = new URL(info.getUrl());//给定网络地址
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();//通过地址打开网络连接
            //获取要下载的文件的大小
            info.setFileSize(Long.parseLong(conn.getHeaderField("CONTENT-LENGTH")));
            conn.disconnect(); //与服务器断开,准备下一次请求(一次请求,一次响应)
            //再次连接、请求
            conn = (HttpURLConnection) url.openConnection();
            /*要想实现续传。我们必须告诉服务器我们当次读取
            *文件的开始位置。相当于我们本地调用seek()
            *因为我们不可能直接调用服务器的对象的方法
            *所以我们只能通过某种方式告诉服务器我们要干什么。
            *让它自行调用自己流对象的seek()到我们想读取的位置。
            *
            * bytes=0-   的意思是告诉服务器从第一个字节开始读
            *            seek(0)
            * bytes=128- 的意思是告诉服务器从第129个字节开始读
            *            seek(128)
            * */
            String prop = "bytes="+info.getPos()+"-";
            //通过连接设置参数,通知服务器从什么地方开始读
            conn.setRequestProperty("RANGE",prop);
            //打开输入流开始读取文件
            InputStream in = conn.getInputStream();
            //将任务中记录的本地文件作为写出的目标文件
            RandomAccessFile raf = new RandomAccessFile(info.getFileName(),"rw");
            //服务器seek的位置就是我们写的位置
            raf.seek(info.getPos());
            //创建一个缓冲区
            byte[] buffer = new byte[1024*10];//10K缓冲区
            int sum = -1;//记录读取的字节数
            /*
            * 进行下载操作
            * 从输入流(来自网络的文件)读取数据
            * 通过输出流(下载的文件)写数据
            * */
            while ((sum=in.read(buffer))>0){
                raf.write(buffer,0,sum);
                //记录当前下载总字节数
                info.setPos(info.getFileSize()+sum);
            }
            raf.close();
            in.close();
            conn.disconnect();//关闭和服务器的连接
        }catch (Exception e){

        }
    }
}

对象序列化

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * Created by 罗强 on 2018/7/12.
 */

public class SerializeObject {
    public static void main(String[] args){
        try {
            //DownloadInfo需实现Serializable接口,否则无法写入文件
            DownloadInfo info = new DownloadInfo(
                    "http://www.baidu.com/download.xxx.zip",
                    "xxx.zip");
            info.setPos(12587);
            info.setFileSize(5566987);
            //将info对象序列化后写入到文件中
            File file = new File("obj.tmp");
            FileOutputStream fos = new FileOutputStream(file);
            //通过oos可以将对象序列化后写入obj.tmp文件中
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            //将info序列化后写出
            oos.writeObject(info);
            oos.close();
            /*反序列化操作*/
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            //反序列化
            DownloadInfo obj = (DownloadInfo) ois.readObject();
            System.out.println(obj.getUrl());
            System.out.println(obj.getFileName());
            System.out.println(obj.getFileSize());
            System.out.println(obj.getPos());//false
            System.out.println(info==obj);
            ois.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读