黑马程序员-【IO流2】

                                                  ------- 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值