Java基础--IO流04(IO流中的其他流,编码)
来源:互联网 发布:软件行业资质认证 编辑:程序博客网 时间:2024/05/22 05:19
操作对象的流
ObjectOutputStream
- 被操作的对象需要实现Serializable(标记接口),该类可以将Java对象的基本数据类型和图形写入OutputStream,可以使用ObjectInputStream读取对象,通过在流中使用文件可以实现对象的持久存储;
- 构造函数:ObjectOutputStream(OutputStream out);
- 常用方法:
write×××(××× obj);
×××:基本数据类型或Object; - 注意:
write(int val)与writeInt(int val)的区别:前者仅读一个int的最低8位,后者写入一个32位的int值;
ObjectInputStream
ObjectInputStream对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化;
1. 构造函数:
ObjectInpuStream(InputStream in)
2. 常用方法:
××× read×××();×××基本数据类型或Object;
3. 注意:static修饰的成员变量不能被序列化;
4. transient关键字;对于非static修饰的成员如果不想被序列化可用该关键字修饰;
import java.io.*;class ObjectStreamDemo { public static void main(String[] args) throws Exception{ //writeObj(); readObj(); } public static void readObj()throws Exception{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt")); Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } public static void writeObj()throws IOException{ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt")); oos.writeObject(new Person("lisi0",399,"kr")); oos.close(); }}
import java.io.*;class Person implements Serializable{ public static final long serialVersionUID = 42L;//自定义序列号ID private String name; transient int age;//非静态成员如果不想被序列化,可以用关键字transient修饰; static String country = "cn";//静态成员不能被序列化。 Person(String name,int age,String country){ this.name = name; this.age = age; this.country = country; } public String toString(){ return name+":"+age+":"+country; }}
管道流
输入输出可以之间进行连接,通过结合线程使用;
PipedOutputStream
- 构造函数:
- PipedOutputStream();可以将PipedOutputStream连接到PipedInputStream来创建通信管道。PipedOutputStream作为发送端;
- PipedOutputStream(PipedInputStream snk);参数中需传入一个管道输入流;
- 若是空参数的构造函数则需要通过connect()方法来获取一个管道输入流,用法:
connect(PipedInputStream snk);
PipedInputStream
- 概述:管道输入流应连接到管道输出流,管道输入流提供要写入管道输出流的所有数据字节,通常数据由某个线程从PipedInpuStream对象读取,并由其他线程将其写入到相应的PipedOutputStream,若为单线程容易死锁线程;
- 构造函数:
- PipedInpuStream(PipedOutputStream src);构造函数无参可用connect(PipedOutputStream src)使此管道输入流连接到管道输出流
import java.io.*;class Read implements Runnable{ private PipedInputStream in; Read(PipedInputStream in){ this.in = in; } public void run(){ try{ byte[] buf = new byte[1024]; System.out.println("读取前。。没有数据阻塞"); int len = in.read(buf); System.out.println("读到数据。。阻塞结束"); String s= new String(buf,0,len); System.out.println(s); in.close(); }catch (IOException e){ throw new RuntimeException("管道读取流失败"); } }}class Write implements Runnable{ private PipedOutputStream out; Write(PipedOutputStream out){ this.out = out; } public void run(){ try{ System.out.println("开始写入数据,等待6秒后。"); Thread.sleep(6000); out.write("piped lai la".getBytes()); out.close(); }catch (Exception e){ throw new RuntimeException("管道输出流失败"); } }}class PipedStreamDemo{ public static void main(String[] args) throws IOException{ PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(); in.connect(out); Read r = new Read(in); Write w = new Write(out); new Thread(r).start(); new Thread(w).start(); }}
RandomAccessFile
- 随机访问文件,自身具备读写的方法;
通过skipBytes(int x);seek(int x);来达到随机访问;
此类的实例支持对随机访问文件的读取和写入; 特点:
- 该类不算是IO体系中的子类而是直接继承Object;但他是IO包中的成员,因为它具备读和写的功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置;
- 其实完成读写的原理就是内部封装了字节输入流和输出流,通过构造函数可以看出,该类只能操作文件,而且操作文件还有模式:只读(r);读写(rw)等;
- 如果模式为只读r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常;
- 如果模式为只读rw,操作的文件不存在,会自动创建,如果存在则不会覆盖;
构造方法:
- RandomAccessFile(File file,String mode);
- RandomAccessFile(String name,String mode);
file-指定文件;
name-系统文件名;
mode-访问模式;
该类常用方法:
- gerFilePointer();返回此文件的当前偏移量;
- length();返回此文件的长度;
- read();该功能与InputStream一样;
- read×××;×××-基本数据类型;
- readLine();读一行;
- seek(long pos);设置指针偏移量;
- setLength(long newLength);设置文件长度;
- write(byte[] b)/(byte[] b,int off,int len)/(int b)该方法与OutputStream方法一样;
- write×××(××× ~);×××基本数据类型;
- skipBytes(int n);跳过指定的字节数;
注:该类的常用方式:通过seek()偏移指针,结合多线程实现分段数据同时读写,实际应用:迅雷下载;
class RandomAccessFileDemo { public static void main(String[] args) throws IOException{ //writeFile_2(); //readFile(); //System.out.println(Integer.toBinaryString(258)); } public static void readFile()throws IOException{ RandomAccessFile raf = new RandomAccessFile("ran.txt","r"); //调整对象中指针。 //raf.seek(8*1); //跳过指定的字节数 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*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.writeInt(97); raf.write("王五".getBytes()); raf.writeInt(99); raf.close(); }}
操作基本数据类型流
DataInputStream
- 构造函数:
- DataInputStream(InputStream in)使用指定的底层输入流,创建一个DataInputStream;
- 常用方法:
- read(byte[] b)/(byte[] b,int off,int len)
- read×××();×××基本数据类型;
- skipBytes(int n);
- readUTF();读取一个有UTF-8修改版格式编码的字符串;
- readUTF(DataInput in);从in中读取由writeUTF写入的数据;
DataOutputStream
- 构造方法:
- DataOutputStream(OutputStream out);创建一个新的数据输出流,将数据写入指定基础输出流;
- 常用方法:
- write(byte[] b,int off,int len);
- write(int b);
- write×××(×××~);×××-基本数据类型;
- writeChars(String s);将字符串按字符顺序写入基础输出流;
- flush();
- size();返回到目前为止写入此数据输出流的字节数;
- writeUTF(String str);以与机器无关方式使UTF-8修改版编码将一个字符串写入基础输出流。
注:writeUTF();写的数据,只能用readUTF()方法读;
注:写入的不同的类型的数据时,读取也要按该顺序读取,否则会出现乱码,因为不同的数据类型的长度不同;
import java.io.*;class DataStreamDemo { public static void main(String[] args) throws IOException{ //writeData(); //readData(); //writeUTFDemo();// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");// osw.write("你好");// osw.close();// readUTFDemo(); } public static void readUTFDemo()throws IOException{ DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt")); String s = dis.readUTF(); System.out.println(s); dis.close(); } public static void writeUTFDemo()throws IOException{ DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt")); dos.writeUTF("你好"); dos.close(); } public static void readData()throws IOException{ DataInputStream dis = new DataInputStream(new FileInputStream("data.txt")); int num = dis.readInt(); boolean b = dis.readBoolean(); double d = dis.readDouble(); System.out.println("num="+num); System.out.println("b="+b); System.out.println("d="+d); dis.close(); } public static void writeData()throws IOException{ DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt")); dos.writeInt(234); dos.writeBoolean(true); dos.writeDouble(9887.543); dos.close(); ObjectOutputStream oos = null; oos.writeObject(new O()); }}
操作字节数组
ByteArrayInputStream
- 构造函数:
- ByteArrayInputStream(byte[] buf);
- ByteArrayInputStream(byte[] buf,int offset,int length);创建ByteArrayInputStream,使用buf作为其缓冲区数组;
- 常用方法:
- available();返回可从输入流读取的剩余字节数;
- read();
- read(byte[] b,int off,int len);
ByteArrayOutputStream
- 构造函数:
- ByteArrayOutputStream();创建一个新的byte数组输出流;
- ByteArrayOutputStream(int size);创建一个新的byte数组输出流,它具有指定大小的缓冲区容量(内部封装缓冲数组);
- 常用方法:
- size();返回缓冲区的当前大小;
- toByteArray();创建一个新分配的byte数组;
- toString();使用平台默认字符集,将缓冲区内容转换为字符串;
- write(int b);
- write(byte[] b,int off,int len);
- writeTo(OutputStream out);将此byte数组输出流的全部内容写入到指定的输出流参数中;
import java.io.*;class ByteArrayStream { public static void main(String[] args) { //数据源。 ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes()); //数据目的 ByteArrayOutputStream bos = new ByteArrayOutputStream(); int by = 0; while((by=bis.read())!=-1){ bos.write(by); } System.out.println(bos.size()); System.out.println(bos.toString()); // bos.writeTo(new FileOutputStream("a.txt")); }}
操作字符数组
如果操作的数据都是字符则使用字符数组的流;该流使用方式与操作字节数组一样;
CharArrayReader
- 构造函数:
- CharArrayReader(char[] buf);
- CharArrayReader(char[] buf,int offset,int length);
- 常用方法:
- read();读取单个字符;
- read(char[] b,int off,int len);将字符读入数组的某一部分;
CharArrayWriter
- 构造函数:
- CharArrayWriter();创建一个新的CharArrayWriter;
- CharArrayWriter(int initialSize);创建一个指定大小的CharArrayWriter;
- 常用方法:
- append(char c);将指定字符添加到此writer;
- flush();刷新流到缓冲区;
- size();返回缓冲区的当前大小;
- toCharArray();返回输入数据的副本;
- toString();将输入数据转换为你字符串;
- write(char[] c,int off,int len);将字符写入缓冲区;
- write(int c);将一个字符写入缓冲区;
- write(String str,int off,int len);将字符串某一部分写入缓冲区;
- writeTo(Write out);将缓冲区的内容写入另一个字符流;
操作字符串
StringReader
- 构造函数:
- StringReader(String s);其源为一个字符串的字符流,创建一个新字符串,reader;
- 常用方法:
- read();读取单个字符;
- read(char[] cbuf,int off,int len);将字符读入数组的某一个部分;
StringWrite
构造函数:
- StringWrite();使用默认初始化字符串缓冲区大小创建一个新的字符串writer;
- StringWrite(int initialSize);使用指定初始字符串缓冲区大小创建一个新字符串 writer;
常用方法:
- append(char c)/(CharSequence csq);将指定字符(或字符序列)添加到此 writer
- flush();刷新该流的缓冲;
- getBuffer();返回该字符串缓冲区本身;
- toString();以字符串的形式返回该缓冲区的当前值;
- write(char[] cbuf,int off,int len);写入字符数组的某一部分;
- write(int c);写入单个字符;
- write(String str);写入一个字符串;
- write(String str,int off,int len);写入字符串的某一部分;
编码表
- 可以指定编码的流:转换流,打印流;
- 最常用:
- InputStreamReader
- OutputStreamWriter
- 只能打印,不能读取:
- PrintStream
- PrintWriter
常见编码表
- ASCII:美国标准信息交换码,用一个字节的7位可以表示;
- ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位表示;
- GB2312:中文编码表;
- GBK:中文编码表升级;
- Unicode:国际标准码;
- UTF-8:最多三个字节表示一个字符;
编码
字符串变成字符数组
String——byte[]:str.getBytes(String charsetName);字符串String方法;charsetName-指定编码表的字符串名称;
解码
byte[]——String:new String(byte[],charsetName);
注:如果中文字符串用“GBK”编码,用“ISO8859-1”解码,会出现乱码(因为不识别),将解码后的乱码再用“ISO8859-1”编码回去,则与“GBK”编码相同(因为不识别,编码未被改变,再用“GBK”解码,则结果为原中文字符串,如果该字符用“UTF-8”去解码,再编码,则编码将发生变化与原“GBK”编码不同,用“GBK”去解码时,结果不是原中文字符串,因为“UTF-8”页识别中文,用“UTF-8”解码再编码后,将按照“UTF-8”编码表中的字符对原解出的乱码进行编码,则结果发生变化,所以只有不识别中文的编码表才能进行解码再编码后,结果不变);
import java.util.*;class EncodeDemo{ public static void main(String[] args)throws Exception { String s = "哈哈"; byte[] b1 = s.getBytes("GBK"); System.out.println(Arrays.toString(b1)); String s1 = new String(b1,"utf-8"); System.out.println("s1="+s1); //对s1进行iso8859-1编码。 byte[] b2 = s1.getBytes("utf-8"); System.out.println(Arrays.toString(b2)); String s2 = new String(b2,"gbk"); System.out.println("s2="+s2); }}import java.io.*;class EncodeStream { public static void main(String[] args) throws IOException { //writeText(); readText(); } public static void readText()throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.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("utf.txt"),"UTF-8"); osw.write("你好"); osw.close(); }}
- Java基础--IO流04(IO流中的其他流,编码)
- IO流4(IO中的其他流、编码)
- Java基础--IO流(四)IO包中的其他流
- 黑马程序员——Java基础---io流(io中的其他对象)
- 黑马程序员java基础之io流中的其他流
- Java基础--IO流之其他流
- Java基础进阶_day12_(其他IO流)
- java 基础之IO流 其他IO类 --08
- Java IO流--IO包中的其他类
- 黑马程序员----Java中的其他IO流
- java---IO流中的其他部分
- Java基础:IO包中的其他类及字符编码
- IO流(四)--IO包中的其他类
- Java--IO流(其他流)
- Java基础知识IO流(其他类)
- java基础---java中的IO流
- 黑马程序员——java基础——IO流中的其他常用类
- Java基础<十六>---> IO之其他流对象
- RabbitMQ学习总结(6)——消息的路由分发机制详解
- 开发问题总结
- 经典算法之线切面(1) 切蛋糕
- 【PHP】数组foreach引发的小问题
- ImageLoader实现Bitmap三级缓存
- Java基础--IO流04(IO流中的其他流,编码)
- Apache Spark源码走读之3 -- Task运行期之函数调用关系分析
- UICollectionViewDelegateFlowLayout
- 易语言 设置组合框高度
- 论狗狗的自我修养
- log4j 1.2 版本实现多日志文件的例子
- 适配器模式(Adapter)—山下的养牛场
- NOI2001年-食物链-并查集-解题报告
- 经典算法之线切面 (2)排序