您的位置:首页 > 职场人生

黑马程序员----IO流(其他)

2015-08-15 22:08 555 查看
——- android培训java培训、期待与您交流! ———-

字节数组操作流

ByteArrayInputStream:

        包含一个缓冲区,该缓冲区包含从流中读取的字节,内部计数器跟踪read方法要提供的下一个字节。    

        在构造的时候需要接受数据源,而且数据源是一个字节数组;   
ByteArrayOutputStream:

        此类实现了一个输出流,其中的数据被写入一个byte数组,缓冲区会随着数据的不断写入而自动增加。

        可以使用toString()和toByteArray()获取数据。

        在构造的时候不用定义数据目的,该对象已经在内部封装了可变长度的字节数组,这就是数据的目的地。

    

因为这两个流对象操作的都是数组,因为没有调用系统底层资源,不用进行流关闭。类中的方法在关闭流后仍然可被使用,而不会产生任何IOException.    

在流操作规律讲解时,讲过源和目的。

源设备:

        键盘:System,in;硬盘:FileStream;内存:ArrayStream.

目的设备:

        控制台:System.out;硬盘:FileStream;内存:ArrayStream.

用流的读写思想来操作数组。

操作字符数组:

        CharArrayReader

        CharArrayWriter

操作字符串:

        StringReader:要有源。

        StringWriter:目的。

public class IO_ByteArrayStream
{
public static void main(String[] args)
{
//数据源:
ByteArrayInputStream bis=new ByteArrayInputStream("ABCDEFG".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"));//只有这一个方法涉及到异常了。
}
}

基本数据类型操作流

可以用于操作基本数据类型的对象;

DataInputStream

DataOutputStream

特殊方法:

    writeUTF(String str):以与机器无关方式使用UTF-8(修改版)编码将一个字符串写入基础输出流。

修改版的UTF-8与标准UTF-8格式之间的不同:

        1.null字节'\u0000'是用2-byte格式而不是1-byte格式编码,因此已编码的字符的字符串中绝不会有嵌入的null.

        2.仅使用1-byte、2-byte和3-byte格式.

        3.增补字符是以代理对象的形式表示的。

public class IO_DataStream
{
public static void main(String[] args) throws IOException
{
writeData();
readData();
writeUTFDemo();
UTF_8Demo();//UTF-8;
GBKDemo();//GBK;
readUTFDemo();
}
//写数据:
public static void writeData() throws IOException
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("c:\\data.txt"));

dos.writeInt(156);
dos.writeBoolean(true);
dos.writeDouble(1569.2);

dos.close();
}
//读取数据:
public static void readData() throws IOException
{
DataInputStream dis=new DataInputStream(new FileInputStream("c:\\data.txt"));

int num=dis.readInt();
boolean b=dis.readBoolean();
double d=dis.readDouble();

System.out.println("num="+num+";b="+b+";d="+d);

dis.close();
}
//writeUTF(String str)方法:
public static void writeUTFDemo() throws IOException
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("c:\\writeUTF.txt"));

dos.writeUTF("写点中文试试");

dos.close();
}
//读取:找与之对应的读取方法readUTF();不然读不出来。
public static void readUTFDemo() throws IOException
{
DataInputStream dis=new DataInputStream(new FileInputStream("c:\\writeUTF.txt"));

String s=dis.readUTF();
System.out.println(s);

dis.close();
}
//正常的UTF-8显示的是怎样的?
public static void UTF_8Demo() throws IOException, FileNotFoundException
{
//转换流:
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("c:\\writeUTF-8.txt"),"UTF-8");

osw.write("写点中文试试");
osw.close();
}
//GBK:
public static void GBKDemo() throws IOException, FileNotFoundException
{
//转换流:
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("c:\\writeGBK.txt"),"GBK");

osw.write("写点中文试试");
osw.close();
}
}

直接操作对象的流

ObjectInputStream

ObjectOutputStream

被操作的对象需要实现Serializable(标记接口)。

public class IO_ObjectInputStream
{
public static void main(String[] args) throws Exception
{
writeObj();
readObj();
}

public static void writeObj() throws IOException
{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("c:\\obj.txt"));

oos.writeObject(new Person1("zhangsan",25));

oos.close();
}

public static void readObj() throws Exception
{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("c:\\obj.txt"));

Person1 p=(Person1)ois.readObject();

System.out.println(p);
ois.close();
}
}

class Person1 implements Serializable //此接口没有方法,没有方法的接口称为标记接口;
{
public static final long serialVersionUID=42L;//UID:给类一个固定标识,自定义UID;

/*private */String name;

//如果对非静态的成员也不想序列化,只要加一个关键字:transient.
transient int age;
static String country="cn";//静态是不能被序列化的;
Person1(String name,int age)
{
this.name=name;
this.age=age;
//this.country=country;//非静态访问静态;
}
public String toString()
{
return name+":"+age+":"+country;
}
}

管道流

PipedInputStream

PipedInputStream

输入输出可以直接进行连接,通过结合线程使用。

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 Writer implements Runnable
{
private PipedOutputStream out;
Writer(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(IOException e)
{
throw new RuntimeException("管道输出流失败");
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class IO_PipedInputStream
{
public static void main(String[] args) throws IOException
{
PipedInputStream in=new PipedInputStream();
PipedOutputStream out=new PipedOutputStream();

in.connect(out);
Read r=new Read(in);
Writer w=new Writer(out);

new Thread(r).start();
new Thread(w).start();

}
}

打印流

该流 提供了打印方法,可以将各种数据类型的数据都原样打印。

printWriter:字符打印流(更常用);构造函数可以接收的参数类型

        1.file对象:File.

        2.字符串路径:String.

        3.字节输出流:OutputStream.

        4.字符输出流:Writer.

printStream:字节打印流;构造函数可以接收的参数类型:

        1.file对象:File.

        2.字符串路径:String.

        3.字节输出流:OutputStream.

可以直接操作文件。

public class IO_PrintStream
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

//PrintWriter out=new PrintWriter(System.out,true);
PrintWriter out=new PrintWriter("c:\\a.txt");//刷新只针对流而言

String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
out.println(line.toUpperCase());
//out.flush();
}
out.close();
bufr.close();
}
}

序列流

SequenceInputStream

    表示其他输入流的逻辑串联,它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,

    接着从第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止。   

多个源对应一个目的:将多个源变成一个源.

public class IO_SequenceInputStream
{
public static void main(String[] args) throws IOException
{
Vector<FileInputStream> v=new Vector<FileInputStream>();
v.add(new FileInputStream("c:\\1.txt"));
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));

Enumeration<FileInputStream> en=v.elements();
SequenceInputStream sis=new SequenceInputStream(en);

//目的:
FileOutputStream fos =new FileOutputStream("c:\\4.txt");

byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}

随机访问文件(RandomAccessFile)

        随机访问文件 ,自身具备读写的方法;

        通过skinBytes(int x),seek(int x)来达到随机访问。

        可以对实现对数据的分段写入;

    

        该类不算IO体系中的子类。而是直接继承Object。但是它是IO包中的成员,因为它具备读和写的功能,内部封装了一个数组,通过指针对数组中的元素进行操作,可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。

    

        其实完成读写的原理就是内部封装了字节输入流和字节输出流。

    

        通过构造函数可以看出,该类只能操作文件。而且操作文件有模式。'r':只读;'rw':读写;而且该对象的构造函数要操作的文件不存在会自动创建,如果存在则不会覆盖;如果模式为只读,不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常。如果模式为读写,那么当文件不存在时,会自动创建,存在则自动覆盖。

    

        可以与多线程结合使用。
public class IO_RandomAccessFile
{
public static void main(String[] args) throws IOException
{
writeFile();
Integer.toBinaryString(97);

readFile();
randomWrite() ;
}
//写:
public static void writeFile() throws IOException
{
RandomAccessFile raf=new RandomAccessFile("c:\\ran.txt","rw");

raf.write("lisi".getBytes());
//raf.write(258);//转换成了不确定的字符;write只获取最低八位,数据丢失了;
raf.writeInt(97);//写出去4个字节;

raf.write("王五".getBytes());
raf.writeInt(99);//写出去4个字节;

raf.close();
}
//读:
public static void readFile() throws IOException
{
RandomAccessFile raf=new RandomAccessFile("c:\\ran.txt","r");//模式是只读,能访问,没有权限。
//raf.write("haha".getBytes());

//调整对象中的指针:
//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);//取出name;
System.out.println("age="+age);//取出年龄;

raf.close();
}
//随机写:
public static void randomWrite() throws IOException
{
RandomAccessFile raf=new RandomAccessFile("c:\\ran.txt","rw");
raf.seek(8*3);//不仅能够进行读写,还能对已经存在的信息进行修改。

raf.write("zhouqi".getBytes());
raf.writeInt(103);
raf.close();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java IO流