IO流

本文详细介绍了Java中的IO流与文件操作,包括字节流与unicode文本流的区别,流家族及其成员,组合流过滤器的应用,文本输入与输出的实现方式,以及二进制数据的读写。此外,还探讨了内存映射文件的使用和随机访问文件的性能考量,并介绍了如何使用ZipInputStream和ZipOutputStream来读写ZIP文件。

 五.IO流  与文件

1

1.1 输入流 输出流

可以从其中读入一个字节序列的对象称为输入流

可以向其中写入一个字节学列的对象称为输出流

  输入输出流的基础是抽象类InputStreamOutputStream,因为面向字节的流不便处理unicode形式存储的信息,(unicode中的每个字符都使用多个字节表示),因此有从抽象类ReaderWriter中继承来的类操作unicode存储的信息,这些类的输入输出操作是基于unicode码元的,而不是基于单字节的字符

 

1.2 读写字节

InputStream  有一个抽象的方法  abstract int read()   所有它的子类都要复写这个方法,才可以读操作,读到末尾,返回-1

OutputStream 有一个抽象的方法  abstract void write( int b)  ,它可以向某个输出位置写出一个字节

完成读写要close()释放资源

 

int read( byte[] b) 读入一个字节数组 ,并返回字节数,如果读到末尾,返回-1

int read (byte[] b,int off ,int len) 读入一个字节数组,off是第一个读入字节的偏移量,len是读入字节的长度 ,该方法返回的是实际读入的字节数

void write ( byte[] b)

void write (byte [] b,int off ,int len)

flush() 将缓冲区的数据发送到目的地,,清空输出流 

close() 清空输出流并关闭流

 

1.3流家族

60

字节流 InputStream  OutputStream 

对应 unicode文本  Reader Writer ,他们的基本方法和字节流类相似

OutputStreamWriterflush方法  ,只有writer类实现了Appendable接口

永远 append()方法

 

组合流过滤器

   例如为了从文件中读入数字,可以这样:

FileInputStream fin = new FileInputStream(  “  employee.dat”);

DataInputStream din= new DataInputStream( fin);

 double s  = din.readDouble();

如果使用缓存机制可以这样写:

 DataInputStream din= new DateInputStream( 

                       new BufferedInputStream(

                             new FileInputStream(“ employee.dat”)

                              ));

 

 

2.文本输入与输出

在保存数据时.我们可以采用二进制形式或者文本形式,二进制形式不方便阅读,本节中我们讨论文本输入和输出 

在下一节中我们讨论二进制的输入和输出

  在存储文本字符串时候需要考虑字符编码,

OutputStreamWriter 可以将unicode编码的字符流转换成字节流 

InputStreamReader 可以将输入流转换成可以产生unicode字符的读入器

例如  InputStreamReader in = new InputStreamReader(System.in);该输入读入器将从键盘读入的数据转换成unicode格式的数据 

可以通过构造器指定编码格式,默认是iso 8859-1

   InputStreamReader in= new InputStreamReader(

new FileInputStream(“employee.txt”)  ,

” utf-8”

);

因为读入器和写出器使用比较普遍,java提供了另外两个类 FileReade FileWriter

FileWriter  fw= new FileWriter(  “ employee.txt”);该方法等同于 

FileWriter fw = new FileWiter( new FileOutputStream  ( ‘employee.txt’));

2.1如何写出文本输出

使用PrintWriter类可以以文本格式打印字符串和数字

 

PrintWriter out= new PrintWriter(employ.txt);

等同于 

PrintWriter out =new PrintWriter(new FileWriter(“ employ.txt”));

自动清空模式,会自动输出到文件中 

String  s=” sgahgj”;

double salary= 5666;

PrintWriter out= new PrintWriter(new FileWriter(employee.txt), true ); 

out.println(s);

out.println(salary);

System.out  System.in  是流,不是写出器和读入器

2.2  如何读入文本输入

 

Scanner  BufferedReader都可以读入文本

(1)BufferedReader in =new BufferedReader( new FileReader(employee.txt)); 

String line;

while ( line= in.readLine()!=null)

{

do something with line

}

 

(2)

Scanner in = new Scanner();//它的方法有 nextInt()  nextDouble()    nextLine()

 hasNextLine()

 

 

while(in.hasNextLine())

{

String line= in.nextLine();

 

}

 

3读写二进制数据  

interface  DateInput 

{

boolean readBoolean();

byte readByte()

char readChar()

int readInt()

void readFully( byte[] b,int off,int len) 将二进制数据读入字节数组中

}

interface DataOutput

void writeByte()

void writeChar()

void writeInt()

void writeChars()

 

 

}

 

它的两个类 DataInputStream  DataOutputStream

随机访问文件

RandomAccessFile类 可以随机在文件的任意位置读或写数据同时实现了DataInputDataOutput 接口,该类和InputStream OutputStream 没有任何关系,是一个继承Object的独立的类,,定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )skipBytes()跳过多少字节数。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数,不支持只写

表示读入

rw 表示读写

RandomAccessFile in = new RandomAccessFile(“employee.dat”,”r”);

RandomAccessFile inout = new RandomAccessFile(“employee.dat”,”rw”);

 

 

  1. public class TestRandomAccessFile {  
  2. public static void main(String[] args) throws IOException {  
  3. RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");  
  4. for (int i = 0; i < 10; i++) {  
  5. //写入基本类型double数据  
  6. rf.writeDouble(i * 1.414);  
  7. }  
  8. rf.close();  
  9. rf = new RandomAccessFile("rtest.dat", "rw");  
  10. //直接将文件指针移到第5个double数据后面  
  11. rf.seek(5 * 8);  
  12. //覆盖第6个double数据  
  13. rf.writeDouble(47.0001);  
  14. rf.close();  
  15. rf = new RandomAccessFile("rtest.dat", "r");  
  16. for (int i = 0; i < 10; i++) {  
  17. System.out.println("Value " + i + ": " + rf.readDouble());  
  18. }  
  19. rf.close();  
  20. }  
  21. }   

 

 

4,ZipInputStream ZipOutputStream 来读写ZIP文件

5.对象流和序列化

对象序列化:将对象写入流中,之后可以读回,每一个对象都对应一个序号,

保存时,如果是第一次保存这个对象,那么给他分配一个序列号,第二次报存这个对象,会告知和之前保存的对象相同,在读回时,当读到一个对象序列号时就会利用流中数据构建这个对象,当第二次读到这个序列号,不再构建对象,而是给它分配这个对象的引用即可

 

用到的类  ObjectOutputStream ObjectInputStream

ObjectOutputStream  out =new ObjectOutputStream(“employee.dat”);

Employ e=new Employ (23,””小明);

Mannage m= new Mannage (40,”xiao qinag”);

out.writeObject(e);

out.writeObject(m);

要存储和恢复这些类必须实现Serializable接口  

public class Employ implements Serializable{}

 

 

 

 

 

 

 

 

 

 

6.新I/0

6.1  内存映射文件

将文件映射到内存中,把这个文件就当作数组来读取,速度会快很多

读写数据的速度 :

内存映射文件>带缓冲的输入流普通输入流>随机访问文件

7.2s 9.9s 100s 160s

随机访问文件性能损失很大

内存映射文件由java.nio这个包负责

1).首先获得通道FileInputStream   FileOutputStream  RandomAccessFile中都有获得通道发动方法  

FileChannel channel= new FileInputStream(“employee.dat”).getChannel();

2)通过FileChannel类的map()方法得到一个MapedByteBuffer,可以指定缓冲区的三种模式 

MapedByteBuffer buff= FileChannel.map(mode ,int off,int length);

3)一旦获得了这个缓冲过区,就可以利用MapedBuffer Buffer超类执行操作

例如   while (buff.hasRemain())

{

 byte b=buffer.get();

}

 

6.2 Buffer超类

文件缓冲区

他有很多子类,例如 ByteBuffer  IntBuffer  

但是注意 StringBuffer和他们完全没有关系 

常用的是ByteBuffer CharBuffer

 

转载于:https://www.cnblogs.com/chuanqimessi/p/4750857.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值