黑马程序员-【IO流2】

来源:互联网 发布:凯撒大帝书籍知乎 编辑:程序博客网 时间:2024/06/06 01:29

                                                  -------android培训java培训、期待与您交流! ----------

字节流转化成字符流

OutputStreamWriter:把字节输出流对象转成字符输出流对象


InputStreamReader:把字节输入流对象转成字符输入流对象


FileWriter和FileReader分别是OutputStreamWriter和InputStreamReader的直接子类,而不是Writer和Reader的直接子类

 

例子:

 

//构建字节输出流对象OutputStream out = new FileOutputStream("");//把字节输出流转成字符输出流Writer w  = new OutputStreamWriter(out);//构建一个字节输入流对象InputStream is = new FileInputStream("");//把字节输入流转成字符输入流Reader r = new InputStreamReader(is);


 

内存操作流

 

之前的文件操作流是以文件的输入输出为主的,当输出的位置变成了内存,那么就称为内存操作流。此时要使用内存流完成内存的输入和输出操作。


如果程序运行过程中要产生一些临时文件,可采用虚拟文件方式实现;

ByteArrayInputStream的构造方法:


public ByteArrayInputStream(byte[] buf):全部内容


public ByteArrayInputStream(byte[] buf,int offset,int length):指定范围的内容


ByteArrayOutputStream的构造方法:


public ByteArrayOutputStream()


例子:

import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;public class ByteArrayDemo7 {public static void main(String[] args) throws IOException {String s = "hello heima";ByteArrayOutputStream bos = new ByteArrayOutputStream();//输出流bos.write(s.getBytes());// 已经把信息写到了内存中byte[] bys = bos.toByteArray();// 得到数据ByteArrayInputStream bis = new ByteArrayInputStream(bys);//输入流,需要源。byte[] b = new byte[1024];int len;while ((len = bis.read(b)) != -1) {String data = new String(b, 0, len);System.out.println(data);}}}package june6D;import java.io.CharArrayReader;import java.io.CharArrayWriter;public class CharArrayDemo8 {public static void main(String[] args) throws Exception {// 用内存字符流先把数据保存到内存中,然后从内存中取出数据String s = "hello workd";CharArrayWriter cw = new CharArrayWriter();cw.write(s);// 数据写到了内存中char[] ch = cw.toCharArray();CharArrayReader cr = new CharArrayReader(ch);char[] b = new char[1024];int len;while ((len = cr.read(b)) != -1) {String data = new String(b, 0, len);System.out.println(data);}}}


 

对象序列化

 

操作的对象为:ObjectInputStream与ObjectOutputStream

 

import java.io.*;class ObjectStreamDemo {public static void main(String[] args) {}public static void writeObj() {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));}}

 

RandomAccessFIle类


RandomAccessFile的唯一父类是Object,与其他流父类不同。是用来访问那些保存数据记录的文件的,这样你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大

小不必相同;但是其大小和位置必须是可知的。


RandomAccessFile是不属于InputStream和OutputStream类系的。实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接

口),它和这两个类系毫不相干,甚至都没有用InputStream和OutputStream已经准备好的功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写

的。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。

 

例子:

 

import java.io.*;class RandomAccessFileDemo {public static void main(String[] args)throws IOException    {        //writeFile();        //readFile();        writeFile_2()    }public static void readFile() throws IOException {RandomAccessFile raf = new RandomAccessFile("ran.txt", "r");// 调整对象指针raf.seek(8);// 跳过指定的字节数raf.skipBytes(8);// 只能往前跳 不能往后跳byte[] buf = new byte[4];raf.read(buf);String name = new String(buf);int age = raf.readInt();System.out.println("name=" + name);System.out.println("age=" + age);raf.close();}public static void writeFile_2() throws IOException {RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");raf.seek(8 * 3);// raf.seek(8*0);//会对数据进行覆写raf.write("周期".getBytes());raf.writeInt(103);raf.close();}public static void writeFile() throws IOException {RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");raf.write("李四".getBytes());// raf.write(258);//write只写出最低八位,超出八位的话会数据丢失raf.writeInt(97);// writeInt(int v) 按四个字节将 int 写入该文件,先写高字节raf.write("王五".getBytes());raf.writeInt(99);raf.close();}}


打印流:PrintWriter和PrintStream

 

打印流有非常好的打印功能,可以打印任何的数据类型。如,整数,小数,字符串等

 

PrintStream类的构造:


public PrintStream(File file) throws FileNotFoundException

public PrintStream(OutputStream out)

实例化的时候依然需要传入一个OutputStream的对象。

PrintWriter和PrintStream都属于输出流,分别针对字符和字节。

PrintWriter和PrintStream重载的print()和println()用于多种数据类型的输出。

print()里的参数不能为空;println()可以

PrintWriter和PrintStream输出操作不抛出异常

PrintStream调用println方法有自动flush功能;

例子:

 

import java.io.FileWriter;import java.io.PrintStream;import java.io.PrintWriter;public class PrintDemo9 {public static void main(String[] args) throws Exception {PrintStream ps = new PrintStream("out.txt");// ps.write(12);ps.println(10086);ps.println(false);ps.println();// 此时就可以                ps = System.out;ps.println("hello!");// 控制台操作,注意上一句// 字符打印流PrintWriter pr = new PrintWriter("out2.txt");// PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream,创建新的 PrintWriter。(构造方法)pr = new PrintWriter(new FileWriter("out2.txt"), true);// 自动刷新,否则的话需要关闭资源!// 与PrintStream不同,若PrintWriter使用了自动刷新方法,那么必须调用println,print,format这些方法的其中一个才可以实现操作pr.println("hello world");pr.println(false);pr = new PrintWriter(System.out, true);// 打印在控制台上pr.println(false);pr.println("nihaoya");pr.println(374822);// pr.close();//因为使用了自动刷新。}}


缓冲流

 

缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写效率,同时增加了一些新的方法。


四种缓冲流

BufferedReader(Reader in)

BufferedReader(Reader in,int sz)//sz表示自定义缓冲区大小

BufferedWriter(Writer out)

BufferedWriter(Writer out,int sz)

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in,int sz)

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out,int sz)

 

BufferedReader提供readLine方法用于读取一行字符串。

BufferedWriter提供了newLine方法用于写入一个行分隔符。等价于//.writer("\r\n");

对于输出的缓冲流,写出的数据会先在内存中缓冲,使用flush方法将会使内存中的数据立刻写出。

例子:

 

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;//用缓冲流,性能相对高些public class BufferedInputStreamDemo22 {public static void main(String[] args) throws IOException {/* * BufferedInputStream bis = new BufferedInputStream(new * FileInputStream("68.txt")); BufferedOutputStream bos = new * BufferedOutputStream(new FileOutputStream("buffer.txt")); *  * int len = 0;  * while((len = bis.read()) != -1){  * bos.write(len);  * } * bos.close();  * bis.close(); */try (BufferedReader br = new BufferedReader(new FileReader("68.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("bufferWriter.txt"))) {//java7新特性,自动关闭资源String Line = null;while ((Line = br.readLine()) != null) {bw.write(Line);bw.newLine();//此时必须加上换行操作,注意这是个新用法(方法)}} catch (Exception e) {e.printStackTrace();}}}



合并流:SequenceInputStream

 

将两个文件的内容合并成一个文件


该类提供的方法:


SequenceInputStream(InputStream s1, InputStream s2) :根据两个字节输入流对象来创建合并流对象。

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.io.SequenceInputStream;//和并两个文件的合并流public class SequenceInputStreamDemo24 {public static void main(String[] args) throws IOException {SequenceInputStream si = new SequenceInputStream(new FileInputStream("hello"),new FileInputStream("world!"));OutputStream ost = new FileOutputStream("sequence.txt");int len;byte []b = new byte[1024];while((len = si.read(b)) != -1){ost.write(b, 0, len);}}}


切割文件

import java.io.*;import java.util.*;class SplitFile {public static void main(String[] args) {// splitFile();merge();}public static void merge()    {        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();                for(int x=1;x<=5;x++)        {            al.add(new FileInputStream("e:\\Java练习\\"+(x++)+".part"))        }                Iterator it = al.iterator();                Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()        {            public boolean hasMoreElements()            {                return it.hasNext();            }            public FileInputStream nextElement()            {                return it.next();            }        };                SequenceInputStream sis = new SequenceInputStream(en);                FileOutputStream fos = new FileOutputStream("e:\\Java练习\\1.mp3");                byte[] buf = new byte[1024];                int len = 0;                while((len=sis.read())!=-1)        {            fos.write(buf,0,len)        }        fos.close();        sis.close();    }public static void splitFile()    {        FileInputStream fis = new FileInputStream("e:\\Java练习\\0.mp3");                FileOutputStream fos = null;                byte[] buf = new byte[1024*1024];                int len = 0;        int x = 1;        while((len=fis.read(buf))!=-1)        {            fos = new FileOutputStream("e:\\Java练习\\"+(x++)+".part")            fos.write(buf,0,len);            fos.close();        }        fis.close();    }}

 

“联通问题”

 

class EncodeDemo2 {public static void main(String[] args) {String s = "联通";byte[] by = s.getBytes("gbk");for (byte b : by) {System.out.println(Integer.toBinaryString(b & 255));}}}


编码

 

 字符流的出现为了方便操作字符,本质上就是对字节流进行了编解码的操作

  主要通过下面子类转换流来完成:InputStreamReader 和OutputStreamWriter

  在两个对象进行构造的时候可以加入字符集

 
  计算机只能识别二进制数据,为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表

  常见的编码表

  ASCII:美国标准信息交换码。 用一个字节的7位可以表示

  ISO08859-1:拉丁码表。欧洲码表

  GBK/GB2312:中文国际编码,专门用来表示汉字

  Unicode:java中使用此编码方式,是最标准的一种编码

 UTF-8:最多用三个字节来表示一个字符


   例子:

import java.io.*;class EncodeStream {public static void main(String[] args) throws IOException {writeText();}public static void readText() throws IOException {InputStreamReader isr = new InputStreamReade(new FileInputStream("gbk.txt"), "gbk");char[] buf = new char[10];int len = isr.read(buf);String str = new String(buf, 0, len);System.out.println(str);isr.close();}public static void writeText() throws IOException {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk");OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"), "UTF-8");osw.write("你好");osw.close();}}
 
0 0
原创粉丝点击