字节流字符流的使用

来源:互联网 发布:莱昂纳德体测数据虎扑 编辑:程序博客网 时间:2024/05/19 22:03

一、基本概念和分类

 字节流的抽象基类
   InputStream,outputStream
字符流的抽象基类
   Reader,Writer

二、数据的读写

1,将数据写到文件当中,使用字节输出流。FileOutputStream

write(byte[] b)将b.length个字节从指定byte数组写入此文件输出流中

<span style="white-space:pre"></span>File dir = new File("tempfile");if(!dir.exists()){    dir.mkdir();}   //1,创建字节输出流,用于操作文件,在对象初始化时,必须明确数据存储的目的地     输出流所关联的目的地如果不存在,会自动创建,如果存在,会覆盖。 FileOutputStream fos = new FileOutputStream("tempfile\\fos.txt"); //2,调用输出流写功能 String str = "abcd"; byte[] buf = str.getBytes(); fos.write(buf); //3,释放资源 fos.close();
2,IOException处理

<span style="white-space:pre"></span>FileOutputStream fos = null;try{    fos = new FileOutputStream("tempfile\\fos.txt");    fos.write("abcd".getBytes());} catch (IOException e) {    e.printStackTrace();} finally {    if(fos!=null)        try{    fos.close();}catch (IOException e){    throw new RuntimeException("失败"+e)}}
3,续写和换行

FileOutputStream(String name,boolean append);是否续写 name - 与系统有关的文件名append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 

实现换行使用到:private static final String LINE_SEPARATOR = System.getProperty("line.separator");

<span style="white-space:pre"></span>FileOutputStream fos = null;try{    fos = new FileOutputStream("tempfile\\fos.txt",true);
<span style="white-space:pre"></span>    //实现换行    String str = LINE_SEPARATOR+"Hello";    fos.write(str.getBytes());} catch (IOException e) {    e.printStackTrace();} finally {    if(fos!=null)        try{    fos.close();}catch (IOException e){    throw new RuntimeException("失败"+e)}}
4,获取一个想要的指定文件的集合

思路:
    1,包含子目录,递归实现
    2,在递归的过程中需要过滤器
    3,满足条件,添加到集合中。


/***    定义一个获取指定过滤器条件的文件的集合*    多级目录下都要用到相同的集合和过滤器,那么就不能在方法中定义集合和过滤器,而是不断的传递*    dir:需要遍历的目录*    list:用于存储符合条件的File对象*    filter:指定的过滤器*/public static void getFileList(File dir,List<File> list,FileFilter filter){    //1,通过listFiles方法获取当前dir目录下的所有文件和文件夹对象    File[] files = dir.listFiles();    //2,遍历该数组    for(File file : files){//3,判断是否是文件夹,如果是文件夹,递归,如果不是,那就是文件,就需要对文件进行过滤if(file.isDirectory()){    getFileList(file,list,filter);}else{    //4,通过过滤器对文件进行过滤    if(filter.accept(file)){list.add(file);    }}    }}/****    定义过滤器*/public class FileFilterBySuffix implements FileFilter{    private String suffix;    public FileFilterBySuffix(String suffix){super();this.suffix = suffix;    }    public boolean accept(File pathname){return pathname.getName().endsWith(suffix);    }}/***    定义一个获取指定过滤器条件的文件集合*/public List<File> fileList(File dir,String suffix){    //1,定义集合    List<File> list = new ArrayList<File>();    //2,定义过滤器    FileFilter filter = new FileFilterBySuffix(suffix);    //调用递归方法    getFileList(dir,list,filter);    return list;}
5,文件的读取

方式一:
   int read() 从此输入流中读取一个数据字节

FileInputStream:从文件系统中的某个文件中获得输入字节,哪些文件可用取决于主机环境。

FileInputStream(File file)通过打开一个到实际文件的连接来创建一个FileInputStream,该实际文件通过文件系统中的File对象file指定
FileInputStream(String name)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

<span style="white-space:pre"></span>File file = new File("tempfile\\fos.txt");if(!file.exists){    throw new RuntimeException("要读取的文件不存在。");}FileInputStream fis = new FileInputStream(file);int by = 0;while(by=fis.read()!=-1){    System.out.println(by);}

方式二:使用缓冲区
   int read(byte[] b)从此输入流中将最多b.length个字节的数据读入一个byte数组中,在某些输入可用之前,此方法将阻塞。 
参数:b:存储读取数据的缓冲区
返回:读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回-1
    //创建一个字节数组
   byte[] buf = new byte[2];


   while(len = fis.read(buf)!=-1){
System.out.println(new String(buf,0,len));
    }


    总结:循环次数少,效率高


6,字节流缓冲区的大小原则

1,一般是1024的整数倍
    private static final int DEFAULT_SIZE = 1024;

   byte[] buf = new byte[DEFAULT_SIZE];

2,available方法
   fis.available();获取与之关联的文件的字节数

    byte[] buf = new byte[fis.available()];创建一个和文件大小一样的缓冲区


总结:不建议使用available方法的方式。如果文件大,容易导致内存溢出。


7,复制文本

思路:    1,读取源数据,将数据写到目的文件中    2,用到流,操作设备上的数据,读用到输入流,写用到输出流    3,而且操作的是文件,需要用到字节流中操作文件的流对象实现:    public static void copyText(){FileInputStream fis = null;FileOutputStream fos = null;try{//1,创建一个输入流和源数据相关联fis = new FileInputStream("");//2,创建一个输出流,并通过输出流创建一个目的文件fos = new FileOutputStream("");//3,创建缓冲区byte[] buf = new byte[1024];//4,定义记录个数的变量int len = 0;//5,循环读写while(len = fis.read(buf)!=-1){    fos.write(buf,0,len);}} catch(IOException e){} finally {    if(fis!=null){try{    fis.close();} catch(IOException e) {    e.printStackTrace();}    }    if(fos!=null){try{    fos.close();} catch(IOException e) {    e.printStackTrace();}    }}    }
8,复制图片原理图解


9,字节流操作中文
   public static void readCNtext() throws IOException{
FileInputStream fis = new FileInputStream("tempfile\\1.jpg");
byte[] buf = new byte[1024];
int len = fis.read(buf);
//将字节数组转成字符串,而且是按照默认的编码表(GBK)进行解码
String s = new String(buf,0,len);
   }



三、字符流

字符流=字节流+编码表

1,字节向字符的桥梁与字符向字节的桥梁

InputStreamReader 能操作字节流的字符流, 字节通向字符的桥梁,将读到的字节进行解码
       OutputStreamWriter 能操作字符流的字节流,字符流通向字节流的桥梁,可使用指定的charset将要写入流中的字符编码成字节。




       构造方法
   OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。
   OutputStreamWriter(OutputStream out, String charsetName)创建使用指定字符集的OutputStreamWriter OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
   OutputStreamWriter(OutputStream out, Charset cs)创建使用给定字符集的 OutputStreamWriter。
   OutputStreamWriter(OutputStream out, CharsetEncoder enc)创建使用给定字符集编码器的 OutputStreamWriter


//使用InputStreamReader读取中文文本    public static void readCNText() throws IOException{<span style="white-space:pre"></span>//1,操作字节流的字符对象,必须先有字节流<span style="white-space:pre"></span>FileInputStream fis = new FileInputStream("tempfile\\cn.txt");<span style="white-space:pre"></span>//2,建立字节通向字符的桥梁<span style="white-space:pre"></span>InputStreamReader isr = new InputStreamReader(fis);<span style="white-space:pre"></span>int ch = 0;<span style="white-space:pre"></span>while((ch=isr.read())!=-1){<span style="white-space:pre"></span>    System.out.println((char)ch);<span style="white-space:pre"></span>}    }
//使用OutputStreamWriter写中文文本    public static void writeCNText() throws IOException{//1,创建字节流对象FileOutputStream fos = new FileOutputStream("tempfile\\GBK.txt");//2,字符通向字节的桥梁OutputStreamWriter osw = new OutputStreamWriter(fos);//3,使用osw的write方法直接写中文字符串。写入数据时,都会存储到缓冲区中因为要查表osw.write("你好");//4,需要刷新缓冲区,将数据同步到目的地中osw.flush();//5,关闭资源,flush()刷新完,流可以继续使用,close刷新完,直接关闭,流结束了,无法再用。osw.close();    }

2,用于操作字符文本文件的便捷类

FileReader
FileWriter
//创建一个用于操作文件的字符输出流对象,内部使用了默认的码表,而且只能操作文件。
FileWriter fw = new FileWriter("tempfile\\fw.txt");

//上述代码等价于以下两句,以下对象可以操作的类型很多。
FileOutputStream fos = new FileOutputStream("tempfile\\fw.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos);


3,用字符流复制文本文件

public static void copyText() throws IOException{    //1,明确数据源,定义字符读取流和数据源相关联    FileReader fr = new FileReader("IO流.txt");    //2,明确数据目的,字义字符输出流,创建存储数据目的    FileWriter fw = new FileWriter("copy.txt");    //3,创建缓冲区    char[] buf = new char[1024];    int len = 0;    while((len=fr.read(buf))!=-1){fw.write(buf,0,len);    }    fw.close();    fr.close();}

4,字符流缓冲区

BufferedReader 方法readLine() 读取一个文本行。
BufferedWriter


public static void WriteTextByBuffered() throws IOException{    //1,明确目的    FileWriter fw = new FileWriter("tempfile\\bufw.txt");    //2,创建缓冲区对象。明确要缓冲的流对象    BufferedWriter bufw = new BufferedWriter(fw);    for(int x = 0;x<=4;x++){bufw.write(x+"abc");//写入一个行分隔符。bufw.newLine();bufw.flush();    }}

5,读键盘录入。

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

0 0
原创粉丝点击