大数据预科班17

来源:互联网 发布:apache服务器显示橙色 编辑:程序博客网 时间:2024/04/30 01:34

大数据预科班17

复习

  • File代表文件或目录--不一定存在--第一次使用时才真正的创建
  • RandomAccessFile--支持对文件读写的类--实际看成一个大型的字节数组

IO流

  • 流动的数据
  • 用于传输数据的API
  • 来源、目的地--方向
  • Input、Output Stream输入输出流
  • 以代码为基准:
  • 当数据是从外部流向程序--输入流--读取文件
  • 当数据是从程序流向外部--输出流--写入文件
  • 根据流的传输方向:传入、传出
  • 跟据流的传输形式:字符流、字节流
  • 四大基本流--都是抽象类
 输入流输出流字符流ReaderWriter字节流InputStreamOutputStream

数据的来源

  • 硬盘---文件
  • 网络
  • 内存
  • 输入设备

向TXT文件写入一个字符串

  • 输出流、字符流,和文件有关
  • OutputStreamWriter下的FileWriter
  • 文件不存在时进行创建
  • 文件存在时,创建并覆盖
  • 无论文件存不存在,都会创建
  • write(“”)//数据死在了缓冲区--为了提高效率,java提供了缓冲区,先写到缓缓区,等缓冲区满了之后才会将数据一次性放到目的地
  • 解决缓冲区死的数据--write.flush();//冲刷缓冲区、
  • 关闭write.close();//关闭流对象--关闭时自动冲刷缓冲区;--流关闭之后,对象依然存在,占用内存--释放流
  • writer=null;//释放内存

流的异常

FileWriter fw=null;//外置定义try{    fw=new FileWriter("E:\\a.txt");    fw.write("aaaa");    fw.flush();//为了防止关流失败导致数据丢失,因此应该提前进行将缓冲输出}catch(Exception e){    e.printStackTrace();}finally{    if(null!=wrirter){        try{            writer.close();        }catch(Exception e){            e.printStackTrack();        }finally{            writer=null;        }    }}1. try外定义并设置为null,try内初始化2. 关流之前判断流对象是否为null3. 为了防止关流失败而导致文件没有释放,需要把流对象强制为为null4. 为了防止关流失败而导致一部分数据丢失,所以提前进行将数据flushyixia

FileReader

  • read返回值为字符所对应的编码--读取到末尾返回-1
  • 字符输入流没有缓冲区--每读取一个字符,就可以输出--可以构建字符数组

FileReader reader = new FileReader("E:\\a.tetx");//自定义缓冲区char[] cs = new char[5];//定义变量来记录读取到的字符个数int len=-1;while((len=reader.read(cs))!=-1){}

剪切文件

package com.peng.demo;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;/** * @author kungfu~peng * @data 2017年9月25日 * @description 剪切文件 */public class QjFile {    // 剪切文件    public void jqFile(File fromFile, File toFile) {        FileReader rf = null;        FileWriter fw = null;        // 将文件进行复制        try {            rf = new FileReader(fromFile);            fw = new FileWriter(toFile);            int len = -1;            char[] flush_char = new char[5];            while ((len = rf.read(flush_char)) != -1) {                fw.write(flush_char, 0, len);            }            fw.flush();        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != rf) {                try {                    rf.close();                } catch (IOException e) {                    e.printStackTrace();                } finally {                    rf = null;                }            }            if (null != fw) {                try {                    fw.close();                } catch (IOException e) {                    e.printStackTrace();                } finally {                    fw = null;                }            }            // 将源文件删除            fromFile.delete();        }        // 将原文件进行删除    }}1. 问题一:    1. 是否可以将文件删除在关流--不可以;文件操作时,其他不可以操作    2. (假设),删除文件时,流操作也就不存在了

缓冲流Buffer。。。

  • 从其他流中获取数据
  • BufferedReader(new FileReader())--从字符输入流中读取数据,提供一个缓冲区,允许按行读取
  • BufferedWriter--作用不大(写操作已经有缓冲区,现在只是更大一点);重点是newLine()换行符
  • 关流--从里到外关流--Stream Alread close
  • 只关外面的流--里面的的也会关闭

转换流InputStreamReader/OuputStreamWriter

  • OutputStreamWriter--字符流通往字节流的桥梁
  • 底层实际上传输的是字节,转换流提供的是将字符转换为字节
  • 没有指定编码--使用系统平台码--windows-gbk;可以自定义编码;

public class QjFile {    public static void main(String[] args) throws Exception {        // 创建文件关联的字节输出流对象        FileOutputStream fos = new FileOutputStream(new File("E:\\a.tet"));        // 创建可以把字符转化为字节的转化流对象,并指定编码        OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");        // 调用转化流,把文字写出去,其实是写到转化流中的缓冲区中        osw.write("您好");        // 关闭流        osw.close();    }}/*当调用OutputStreamWriter对象的writer方法时,  会拿着字符到指定的码表中进行查询,  把查到的字符编码值转换成字节数存放到OutputStreamWriter缓冲区中,  最后在调用刷新功能或者关闭流,将缓冲区的字节数据写到指定文件中*/
  • InputStreamReader--字节流通往字符流的桥梁
  • 底层实际上(FileInputStream)传输的是字节,转换流提供的是将字节转为字符
  • 没有指定编码--使用系统平台码;windows-gbk;可以自定义编码;

public class QjFile {    public static void main(String[] args) throws Exception {        // 创建读取文件的字节流对象        FileInputStream in = new FileInputStream(new File("E:\\a.txt"));        // 创建转换流对象        InputStreamReader isr = new InputStreamReader(in, "utf-8");        // 使用转换流读取字节流中的字节        int ch = -1;        while ((ch = isr.read()) != -1) {            System.out.println((char) ch);        }        isr.close();    }}/*它使用指定的字符集可以由名称指定或显示给定,或者可以接受平台默认的字符集*/
  • 字符转换原理--字节流+编码表
总结:   字节->编码表->字符看不懂的->看得懂的需要读。输入流InputStreamReader字符->编码表->字节看的懂得->看不懂的需要写。输出流OutputStreamWriter

流继承关系

  • Writer->OutputStreamWriter->FileWriter
  • Reader->InputStreamWriter->FileReader

字节缓冲流

  • 字节缓冲输出流BufferedOutputStream

public class QjFile {    public static void main(String[] args) throws Exception {        // 创建基本的字节输出流        FileOutputStream fileOut = new FileOutputStream("a.txt");        // 使用高效的流,把基本的流进行封装,实现速度的提升        BufferedOutputStream out = new BufferedOutputStream(fileOut);        // 写数据        out.write("hello".getBytes());        // 关闭流        out.close();    }}
  • 字节缓冲输入流BufferedInputStream

public class QjFile {    public static void main(String[] args) throws Exception {        // 创建缓冲流对象        FileInputStream fileIn = new FileInputStream(new File("a.txt"));        // 把基本的流包装成高效的流        BufferedInputStream in = new BufferedInputStream(fileIn);        // 读数据        int ch = -1;        while ((ch = in.read()) != -1) {            System.out.println((char) ch);        }        // 关闭        in.close();    }}

字符缓冲流

  • 字符缓冲输出流BufferedWriter

public class QjFile {    public static void main(String[] args) throws Exception {        // 创建流        // 基本字符输出流        FileWriter fileOut = new FileWriter("a.txt");        // 把基本的流进行包装        BufferedWriter out = new BufferedWriter(fileOut);        // 写数据        for (int i = 0; i < 5; i++) {            out.write("hello");            out.newLine();// 写入换行符        }        // 关闭流        out.close();    }}
  • 字符缓冲输入流BufferedReader

public class QjFile {    public static void main(String[] args) throws Exception {        // 创建流        BufferedReader in = new BufferedReader(new FileReader("a.txt"));        // 读数据        String line = null;        while ((line = in.readLine()) != null) {            System.out.println(line);        }        // 关闭流        in.close();    }}

流的操作规律

  • 明确一:要操作的数据是数据源还是数据目的
    • 源:InputStream Reader
    • 目的:OutputStream Writer
    • 先根据需求明确要读,还是要写
  • 明确二:要操作的数据是字节还是文本
      • 字节:InputStream
      • 文本:Reader
    • 目的
      • 字节:OutputStream
      • 文本:Writer
  • 明确三:吗明确数据所在的具体设备
    • 源设备
      • 硬盘:文件 以File开头
      • 内存:数组,字符串
      • 键盘:System.in
      • 网络:Socket
    • 目的设备
      • 硬盘:文件 File
      • 内存:数组,字符串
      • 屏幕:System.out
      • 网络:Socket
  • 明确四:是否需要额外功能呢?
    • 额外功能:
      • 转换吗? 转换流 InputStreamReader OutputStreamWriter
      • 高效吗? 缓冲区对象,BufferedInputStream/BufferedOutputStream BufferedWriter/BufferedReader

字节流

  • 不存在缓冲区字
  • close关流,释放资源
  • 字节流可以读取任意文件
  • java的原生的流(字符流)对office组件支持的不好---POI操作组件

练习

  • 利用转换流来改变文件的编码

package com.peng.demo;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;/** * @author kungfu~peng * @data 2017年9月25日 */public class QjFile {    public static void main(String[] args) throws Exception {        changeCode();    }    // 改变文件的编码    public static void changeCode() throws Exception {        // 创建新文件        File toFile = new File("E:\\b.txt");        File fromFile = new File("E:\\a.txt");        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(                toFile), "utf-8");        // 读取源文件        InputStreamReader isr = new InputStreamReader(new FileInputStream(                fromFile), "gbk");        int s = -1;        char[] data = new char[10];        // 文件a的内容复制进b文件        while ((s = isr.read(data)) != -1) {            osw.write(data);        }        isr.close();        osw.close();        // 将a文件删除        fromFile.delete();        // 将文件b改名        toFile.renameTo(new File("E:\\c.txt"));    }}

系统流/标准流

  • 系统都是字节流
  • System.out()标准输出流
  • System.in()标准输入流
  • System.err()标注错误流
  • out和err再使用时没有任何差别,只是在输出结果有颜色差别;正常结果--out,错误结果--err
  • 线程不安全--out和err--同行或上下位置变化

练习

  • 用BufferedReader和System.in来实现输入和获取一行数据

package com.peng.demo;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;/** * @author kungfu~peng * @data 2017年9月25日 */public class FileTest {    public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        System.out.println(br.readLine().toString());        br.close();    }}/*关闭时in也关闭了,不能二次获取*/

打印流

  • PrintStream/PrintWriter--可以传入一个输出流,更改格式后输出
  • print(XX xx)没有无参函数
  • println(XX xx)有有参函数
  • 注意:除char[]引用数据类型打印字符串,其他的都是打印地址

合并流

  • 提出:增强用户体验
  • SequenceInputStream(InputStream i1,InputStream i2);
  • SequenceInputStream(Enumeration e);//利用Vector--elements
  • 只有合并输入流,没有合并输出流
  • 不能控制字符集

package com.pneg.io2;import java.io.FileInputStream;import java.io.InputStream;import java.io.SequenceInputStream;import java.util.Enumeration;import java.util.Vector;/** * @author kungfu~peng * @data 2017年11月8日 * @description */public class SquenceStreamDemo {    public static void main(String[] args) throws Exception {        // 分别出创建输入流来指向要合并的文件        FileInputStream in1 = new FileInputStream("a.txt");        FileInputStream in2 = new FileInputStream("b.txt");        FileInputStream in3 = new FileInputStream("c.txt");        // 创建一个Vector对象存入流        Vector<InputStream> ins = new Vector<InputStream>();        ins.add(in1);        ins.add(in2);        ins.add(in3);        // 需要将集合转化为一个枚举对象        Enumeration<InputStream> e = ins.elements();        // 创建合并流对象        SequenceInputStream sis = new SequenceInputStream(e);        // 读取数据        byte[] data = new byte[1024];        int len = -1;        while ((len = sis.read(data)) != -1) {            System.out.println(new String(data, 0, len));        }    }}

  • 练习:文件切块
    • 文件越多,打开越慢
    • 创建足够多的文件放置
    • 文件的存储位置--记录

操作内存的类

  • StringReader
  • StringWriter
  • CharArrayOutputStream
  • ByteArrayOutputStream