黑马程序员------IO流使用

来源:互联网 发布:windows xp安装版iso 编辑:程序博客网 时间:2024/06/05 00:57

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

Properties:属于map集合,不用指定泛型,内部只能存放字符串类型
方法:
p.put();放入字符串
p.loag(输入流)
p.store(输出流,注释)
p.clear();”清空集合”
p.containsKey(key);”是否包含某个key”
p.containsValue(value);”是否包含某个value”
p.entrySet();”返回Set集合,包含所有键值对信息”
p.keySet();”返回Set集合,包含所有键”
p.get(key);”根据key获取value”
p.getProperty(key);”根据key返回键,返回值是string类型”
p.getProperty(key, defaultValue);”根据key返回键,返回值是string类型,没有值的时候使用默认值”
p.isEmpty();”集合是否为空”
p.size();”集合长度”

    public static void propertiesDemo() {        Properties p = new Properties();        p.put("zhangsan", "10");        p.put("zhangsan1", "101");        p.put("zhangsan2", "102");        p.put("zhangsan3", "103");        "//把Properties 内的数据以列表形式输出"        p.list(new PrintStream(System.out));        "/**         * 模拟load()和store()         * load():读取的文件内部必须是键值对的形式,         * a = b         */"        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));        String line = null;        try {            while ((line = br.readLine()) != null) {                if ("over".equals(line))                    break;                    "//对字符串根据 = 分割"                String[] s = line.split("=");                bw.write(s[0] + " : " + s[1]);                bw.flush();                "//换一行"                bw.newLine();            }            br.close();            bw.close();        } catch (IOException e) {            e.printStackTrace();        }        "/**         * 使用load和stroe来加载文件和输出文件         */"        try {            "//读取文件"            p.load(new FileInputStream("d://c.txt"));            "//把p对象中的内容写入到文件中"            p.store(new OutputStreamWriter(new FileOutputStream("c://cc.txt"), "utf-8"));        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

RandomAccessFile 随机文件读写
(即可以读,也可以写,创建对象时声明权限即可,r:读,w:写)
raf.setLength(newLength);设置一个文件的大小(设置后文件大小立即为设置的大小,凡是内部没有数据)
raf.length();获取文件大小
raf.read();读取文件
raf.write();写文件:可以读写基本数据类型
raf.readLine();读取一行
raf.seek(int);从哪里开始读取或写入
raf.skipBytes(n);跳过多少字节
可以多个RandomAccessFile 对象同时对一个文件进行读写操作(多线程下载)

    public static void demo3() {        try {            "通过url获取网络资源对象"            URL url = new URL("http://127.0.0.1:8080/demo.avi");            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            conn.setRequestMethod("GET");            conn.setReadTimeout(3000);            conn.connect();            InputStream in = conn.getInputStream();            "获取网络文件大小"            long length = conn.getContentLength();            "创建本地文件,并设置大小"            File file = new File("c://demo//t.avi");            if (file.exists()) {                file.delete();                file.createNewFile();            } else {                file.createNewFile();            }            RandomAccessFile raf = new RandomAccessFile(file, "rw");            "设置文件大小,只有RandomAccessFile才有这个方法"            raf.setLength(length);            raf.close();            conn.disconnect();            "开启三个线程,并传入开始和结束位置"            method(0, length / 3);            method(length / 3, length / 3 * 2);            method(length / 3 * 2, length);        } catch (Exception e) {            e.printStackTrace();        }     }    public static void method(final long start, final long end) {        new Thread(new Runnable() {            @Override            public void run() {                File file = new File("c://demo//t.avi");                if (!file.exists()) {                    throw new RuntimeException("找不到文件");                }                try {                    "三个线程共三个RandomAccessFile对象,                    他们同时操作一个文件"                    RandomAccessFile raf = new RandomAccessFile(file, "rwd");                    "设置URL"                    URL url = new URL("http://127.0.0.1:8080/demo.avi");                    "获取httpUrlConnextion对象"                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();                    "连接方法"                    conn.setRequestMethod("GET");                    "读取超时时间"                    conn.setReadTimeout(3000);                    "设置提交属性"                    conn.setRequestProperty("Range", "bytes=" + start + "-" + end);                    conn.connect();                    System.out.println("开始下载:" + Thread.currentThread());                    System.out.println("开始下载:" + start + "  :  " + end);                    InputStream in = conn.getInputStream();                    byte[] by = new byte[1024];                    "设置从文件哪个位置开始写入数据"                    raf.seek(start);                    while ((len = in.read(by)) != -1) {                        "写入数据"                        raf.write(by, 0, len);                    }                    System.out.println("关闭:" + Thread.currentThread());                    raf.close();                } catch (Exception e) {                    e.printStackTrace();                }             }        }).start();    }

PrintStream
只有输出流,没有输入流
可以操作字节流和字符流,一般经常使用字符流
一般使用在打印日志信息中,方便

    public static void demo2() {        try {            File f = new File("c://demo//b.txt");            int[] i = new int[1];            i[3] = 4;        } catch (Exception e) {            try {                "获取时间"                Date date = new Date();                "当参数是输出流的时候,可以指定自动刷新,指定自动刷新后只有println(),printf(),formar()方法有用,若参数是file,不能设置自动刷新                print()不会自动刷新"                "FileOutputStream 若文件已经存在采用追加模式,我不是覆盖"                PrintStream ps = new PrintStream(new FileOutputStream("c://demo//d.txt"true),                        true);                "打印的是字节流"                ps.write(date.toString().getBytes());                "打印时间,打印的是字符流"                ps.println(date);                "把异常信息打印到ps对象中"                e.printStackTrace(ps);            } catch (FileNotFoundException e1) {                throw new RuntimeException("日志文件创建失败!");            }        }    }

LinenumberReader:
没有LinenumberWriter
使用lnr.getLineNumber()获取行号,默认从0开始
使用lnr.setLineNumber(10);这是行号的起始位置
LinenumberReader自带缓存,有readLine()方法

    public static void lineNum() {        LineNumberReader lnr = null;        BufferedWriter bw = null;        try {            lnr = new LineNumberReader(new FileReader("d://demo.txt"));            bw = new BufferedWriter(new FileWriter("c://demo.txt"));            String line = null;            "设置行号从10开始"            lnr.setLineNumber(10);            while ((line = lnr.readLine()) != null) {                bw.write(lnr.getLineNumber() + " : " + line);                "// 最好使用自带的方法换行,这样可以跨平台"                bw.newLine();                bw.flush();            }        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {            "关闭资源"            try {                if (lnr != null)                    lnr.close();            } catch (IOException e) {                e.printStackTrace();            }            try {                if (bw != null)                    bw.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }

流的切割和合并
序列流:
对流进行合并,只有InputStream,不能使用字符流(Reader,Writer)
输入流是一个有序集合,当读取到第一个流的末尾处,会继续读第二个流的开始,直到结束

    public static void sequenceInputStream() {        "/**         * 文件的切割         * 实际上就是在输出时候指定输出的大小         * 例:定义的缓冲区大小是多大,那么分割的就是多大         */"        FileInputStream fis = null;        FileOutputStream fos = null;        try {            "// 获取文件输入流"            fis = new FileInputStream("d://love.mp3");            int num = 0;            int count = 0;"// 文件名的计数"            "// 缓存大小是1m"            byte[] by = new byte[1024 * 1024];            while ((num = fis.read(by)) != -1) {                count++;                "/**                 * 在内部进行创建输出流,当第一个数组存满后                 * 创建输出流进行存储,然后立刻关闭                 * 当再次循环的时候重新创建输出流,重新放新的数据                 */"                fos = new FileOutputStream("c://" + count + "1.part");                fos.write(by, 0, num);                fos.flush();                fos.close();            }            fis.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        "// 声明集合,内部存放输入流,若是输入流数量小于两个不用创建集合,直接使用构造方法传递就可以"        ArrayList<FileInputStream> list = new ArrayList<FileInputStream>();        try {            "// 添加输入流"            list.add(new FileInputStream("c://11.part"));            list.add(new FileInputStream("c://21.part"));            list.add(new FileInputStream("c://31.part"));            "// 获取每一个输入流,由于被Enumeration使用,他是匿名内部类,要使用final修饰"            final Iterator<FileInputStream> it = list.iterator();            "/**             * SequenceInputStream中只能接收Enumeration集合,不能使用Iterator             * 使用Enumeration集合是vector,但是已经被ArrayList代替             * 所以重写Enumeration的方法             */"            Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {                @Override                public boolean hasMoreElements() {                    return it.hasNext();"// 是否有下一个"                }                @Override                public FileInputStream nextElement() {                    return it.next();"// 获取下一个对象"                }            };            FileOutputStream fos2 = new FileOutputStream("c://lov1.mp3");            SequenceInputStream sis = new SequenceInputStream(en);            "/**             * 最后进行输出             */"            int num = 0;            byte[] by = new byte[1024];            while ((num = sis.read(by)) != -1) {                fos2.write(by, 0, num);            }            sis.close();            fos2.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

对象的持久化存储:
ObjectOutputStream,ObjectInputStream
将一个对象进行持久化存储,存储的对象必须实现Serializable接口,打上标记
实现Serializable的类默认会生成一个UId:
public static final long serialVersionUID = 10;
它会根据这个值进行判断是不是原来的对象,默认是根据类中的成员进行计算,也可以手工指定
当对象进行持久化存储后,这时候修改了类中的一些值,例如添加了一个成员等
这时候再读取对象文件的时候会报错:java.io.InvalidClassException
静态不能被序列化
非静态不想被序列化使用关键字:transient

    public static void serializable() {        ObjectOutputStream oos = null;        ObjectInputStream ois = null;        try {            oos = new ObjectOutputStream(new FileOutputStream("d://demo2.txt"));            ois = new ObjectInputStream(new FileInputStream("d://demo2.txt"));            "// 写入一个对象"            oos.writeObject(new Persion("lisi", 31));            oos.writeObject(new Persion("lisi1", 31));            oos.writeObject(new Persion("lisi2", 32));            oos.close();            "// 读取一个对象,并进行强转"            Persion p = (Persion) ois.readObject();            Persion p1 = (Persion) ois.readObject();            Persion p2 = (Persion) ois.readObject();            System.out.println(p.getName() + "  " + p.getAge());            System.out.println(p1.getName() + "  " + p1.getAge());            System.out.println(p2.getName() + "  " + p2.getAge());        } catch (Exception e) {            e.printStackTrace();        }     }import java.io.Serializable;public class Persion implements Serializable {    private static final long serialVersionUID = 1;    private String name;    private int age;    public Persion(String name, int age) {        super();        this.name = name;        this.age = age;    }}

管道流:
PipedInputStream PipedOutputStream
一般应用在多线程中,一个线程负责输入,而另一个线程负责输出
当一段连接线程提前结束的时候:会报错

    public static void guanDaoDemo() {        "创建一个输入管道流,这里使用了匿名内部类,局部变量要声明为final"        final PipedInputStream pis = new PipedInputStream();        "创建一个输出管道流"        final PipedOutputStream pos = new PipedOutputStream();        try {            "两个流进行连接"            pis.connect(pos);        } catch (IOException e) {            e.printStackTrace();        }        "输出管道流"        new Thread(new Runnable() {            @Override            public void run() {                int num = 0;                System.out.println("正在读取数据...");                try {                    while ((num = pis.read()) != -1) {                        System.out.println(num);                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();        "输入管道流"        new Thread(new Runnable() {            @Override            public void run() {                try {                    System.out.println("正在写入数据...");                    Thread.sleep(3000);                    pos.write("--------".getBytes());                    System.out.println("写入完成...");                } catch (IOException e) {                    e.printStackTrace();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }).start();    }

存储基本数据类型
DataInputStream,DateOutputStream
注意:
写入顺序和读取顺序必须相同(第一个写入的是int类型,则读取的时候第一个必须是int类型,如果是long类型,则会多读取数据,造成数据错误)
gbk编码表:一个中文占2个字节
utf -8:一个中文占3个字节
utf-8改:一个中文占4个字节
当存储的数据大于256时,最好是用writeInt(),他是直接存储32位,而write()只是存储8位,
会造成损失精度
writeUTF(“你好”);当写入时使用了这个方法,取出时一定要使用readUTF();取出

public static void dataDemo() {        try {            DataInputStream dis = new DataInputStream(new FileInputStream("d://demo3.txt"));            DataOutputStream dos = new DataOutputStream(new FileOutputStream("d://demo3.txt"));            dos.writeInt(78);"// 写入32位"            dos.write(455);"// 写入8位,会造成精度损失"            dos.writeBoolean(true);            dos.writeUTF("你好");            dos.close();            int a = dis.readInt();            int b = dis.read();            boolean c = dis.readBoolean();            String s = dis.readUTF();            System.out.println(a + " " + b + " " + c + " " + s);        } catch (FileNotFoundException e) {        } catch (IOException e) {            e.printStackTrace();        }    }

字节数组操作数据,字符数组,字符串:
ByteArrayInputStream ByteArrayOutputStream
实例:把文件的中内容读取到内存中
不需要关闭,因为没有调用底层资源,关闭也没用
bos.size()获取输出长度
这个是直接输出到内存中

    public static void arrayDemo() {        BufferedReader br;        try {            "读取一个文件"            br = new BufferedReader(new FileReader("d://demo.txt"));            "定义输出文件"            FileOutputStream fos = new FileOutputStream("d://demo4.txt");            StringBuilder sb = new StringBuilder();            String line = null;            "把文件读取的内容添加到StringBuilder中"            while ((line = br.readLine()) != null) {                sb.append(line);            }            System.out.println(sb.toString());            "// 读取字节数据"            ByteArrayInputStream bis = new ByteArrayInputStream(sb.toString().getBytes());            "ByteArrayOutputStream 是把数据写入到内存中"            ByteArrayOutputStream bos = new ByteArrayOutputStream();"// 长度自动增加"            int by = 0;            while ((by = bis.read()) != -1) {                "// 输出,这里是输出到内存中"                bos.write(by);            }            "// 输出到outputstream,必须要先执行完上面while循环,把数据写入内存后,才能执行writeTo()"            bos.writeTo(fos);        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

0 0
原创粉丝点击