Java day 18-19

Day18

一、文件的字节输入流与输出流

1.使用字节流读数据

                 public FileInputStream(Stringname)

开发步骤:

1):创建字节文件输入流对象

2)读数据

3)释放资源

读数据的两种方式:

1)public int read():一次读取一个字节

2)public int read(byte[] b):一次读取一个字节数组

一次读取一个字节数组的速率比一次读取一个字节快。

运用while循环读取,当该文件读取完后 ,返回-1就是结束条件

例:

import java.io.FileInputStream;

import java.io.IOException;

public class FileInputStreamDemo {

  public static void main(String[] args) throws IOException {

         FileInputStream fis = new FileInputStream("a.txt");

         //方法一:一次读取一个字节

//      int by=0;

//      while((by=fis.read())!=-1){

//               System.out.println((char)by);

//      }

         //方法二:一次读取一个字节数组

         byte [] bys=new byte[1024];

         int len=0;

         while((len=fis.read(bys))!=-1){

                   System.out.println(newString(bys,0,len));

         }

         fis.close();

}

}

2.使用字节输入流和字节输出流复制文件

1)E盘下有个geek.exe文件,将其内容复制到当前项目下“清理工具.exe”中

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class Copy {

         publicstatic void main(String[] args) throws IOException {

                   //封装数据源

                   FileInputStream fis = new FileInputStream("E:\\geek.exe");

                   //封装目的地

                   FileOutputStream fos = new FileOutputStream("清理工具.exe");

                   //读写操作

                   //一次读取一个字节

                   int bys = 0;

                   while((bys = fis.read()) != -1) {

                            //写数据

                            fos.write(bys);

                   }

                   //释放资源

                   fis.close();

                   fos.close();

         }

}

3.由于字节数组比一次读取一个字节更快,从而引出类更高效的一种流:字节缓冲流

字节缓冲输入流:BufferedInputStream

    字节缓冲输出流:BufferedOutputStream

     字节缓冲输出流构造方式:

     public BufferedOutputStream(OutputStream out):默认缓冲区大小(默认缓冲大小已经足够大了)

  为什么字节缓冲流不能直接针对文件进行操作呢?

    缓冲流只是提供一个缓冲区,针对IO进行实现数据的传输实际是通过底层基本流进行实现的,所以缓冲流不能直接对文件操作。

 flush()和close()方法的区别?

 flush():刷新缓冲区的流,强迫将缓冲字节都写到该流中,刷新之后是可以写数据的。

 close():关闭流对象所指向指向的这个资源文件,一旦关闭,写数据,写不进去的。

字节缓冲输入流构造方法:

  public BufferedInputStream(InputStreamin) :指定默认缓冲区大小创建字节缓冲输入流对象

     缓冲输入流:一次读取一个字节:

                         一次读取一个字节数组

                        两种方式的读取任选一种

4. 对于图片文件,音频文件,视频文件,优先采用字节缓冲输入流(高效流)一次读取一个字节数组。复制时间比较。

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class FileDemo {

         publicstatic void main(String[] args) throws IOException {

                   long startTime = System.currentTimeMillis();

//               method1("D:\\01_回顾内容.exe","a1.exe");//共耗时:223618毫秒

                    method2("D:\\01_回顾内容.exe","a2.exe");//共耗时:440毫秒

//               method3("D:\\01_回顾内容.exe","a3.exe");//共耗时:149302毫秒

//               method4("D:\\01_回顾内容.exe","a4.exe"); //共耗时:422毫秒

                   long endTime = System.currentTimeMillis();

                   System.out.println("共耗时:" +(endTime - startTime) + "毫秒");

         }

//   高效字节流(字节缓冲输入流)一次读取一个字节数组

//      private static void method4(String srcString, String destString) throws  IOException{

//      BufferedInputStream bis = new BufferedInputStream(new

//      FileInputStream(srcString)) ;

//      BufferedOutputStream bos = new BufferedOutputStream(new

//      FileOutputStream(destString)) ;

//      byte[] bys = new byte[1024] ;

//      int len = 0 ;

//      while((len=bis.read(bys))!=-1){

//      bos.write(bys, 0, len) ;

//      bos.flush() ;

//      }

//      bis.close() ;

//      bos.close() ;

//      }

//  高效字节流(字节缓冲输入流)一次读取一个字节

//      privatestatic void method3(String srcString, String destString)

//                         throwsIOException {

//               BufferedInputStreambis = new BufferedInputStream(new FileInputStream(

//                                  srcString));

//               BufferedOutputStreambos = new BufferedOutputStream(

//                                  newFileOutputStream(destString));

//               intby = 0;

//               while((by = bis.read()) != -1) {

//                         bos.write(by);

//                         bos.flush();

//               }

//               bis.close();

//               bos.close();

//      }

//  基本字节流(FileInputStream)一次读取一个字节数组

         privatestatic void method2(String srcString, String destString)

                            throwsIOException {

                   FileInputStreamfis = new FileInputStream(srcString);

                   FileOutputStreamfos = new FileOutputStream(destString);

                   byte[]bys = new byte[1024];

                   intlen = 0;

                   while((len = fis.read(bys)) != -1) {

                            fos.write(bys,0, len);

                   }

                   fis.close();

                   fos.close();

         }

//   基本字节流(FileInputStream)一次读取一个字节

//      private static void method1(String srcString, String destString) throws

//      IOException {

//      // TODO Auto-generated method stub

//      FileInputStream fis = new FileInputStream(srcString);

//      FileOutputStream fos = new FileOutputStream(destString) ;

//      int by = 0 ;

//      while((by=fis.read())!=-1){

//      fos.write(by) ;

//      }

//      fis.close() ;

//      fos.close() ;

//      }

}

5. 字节流一次读取一个字节,出现了中文乱码:

   原因是:给字节进行强制类型转换,代码的注释中有中文,并且平台默认编码:GBK格式:一个中文对应的两个字节

   使用字符流来进行操作:字符流就必须指定编码格式

计算机是如何识别中文的?

1)每个中文左边对应的字节一定是负数

 2)GBK格式:右边的字节可以中正数,可以是0,可以是负数

import java.util.Arrays;

public class Demo {

         publicstatic void main(String[] args) {

                   //定义一个字符串

                   //String s = "abcdefg" ;

                   //[97, 98, 99, 100, 101, 102, 103]

                   Strings = "我爱学Java";

                   //当前平台默认的编码集:GBK:一个中文对应两个字节

                   //[-50, -46, -80, -82, -47, -89, 74, 97, 118, 97]

                   //将当前字符串转换成字节数组

                   byte[]bys = s.getBytes();

                   System.out.println(Arrays.toString(bys));

         }

}

编码:就是能看懂的字符串转换成看不懂的字节数组

        public byte[] getBytes(Charset charset):将字符串转换成字节数组,指定编码格式(字符集)

解码:就是将看不懂的字节数组----->能看懂的:将字节数组--->字符串

        public String(byte[] bytes, Charset charset)通过使用指定的 编码格式 解码指定的 byte 数组,构造一个新的String。

import java.io.IOException;

import java.util.Arrays;

public class StringDemo2 {

         publicstatic void main(String[] args) throws IOException {

                   Strings = "我爱看书";

                   //编码

                   //byte[] bys = s.getBytes("utf-8") ;

                   //utf-8:[-26, -120, -111, -25, -120, -79, -25, -100, -117, -28, -71, -90]

                   //如果不写编码格式:默认GBK

                   byte[] bys = s.getBytes();// GBK[-80, -82, -60, -29]

                   //System.out.println(bys);

                   System.out.println(Arrays.toString(bys));

                   //解码

                   //public String(byte[] bytes, Charset charset)

                   //String str = new String(bys, "GBK") ;

                   String str = new String(bys);// 默认GBK

                   System.out.println(str);//我爱看书

         }

}

二、字符输入流和输出流

1.      字符输入流:字节输入流+编码格式(默认GBK)

例:

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

public class InputStreamReaderDemo {

         publicstatic void main(String[] args) throws IOException {

                   InputStreamReaderisr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");// 默认为GBK格式,可以不写

                   char []chs = new char[1024];

                   int len = 0;

                   while((len = isr.read(chs)) != -1) {

                            System.out.println(newString(chs, 0, len));

                   }

                   isr.close();

         }

}

2.字符输出流:Writer:是一个抽象类

使用的是该抽象类的子类:OutputStreamWriter------>字符转换流:可以将字节输出流转换字符流

public OutputStreamWriter(OutputStreamout,Charset cs):创建一字符输出转换流对象,指定编码格式

字节输出流+编码格式---->字符输出流

编码格式:使用平台的默认编辑集进行编码:GBK

例:

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStreamWriter;

public class OutStreamWriterDemo {

         publicstatic void main(String[] args) throws IOException {

                   OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),"GBK");// 默认为GBK格式,可以不写

                   osw.write("中国我爱你");

                   osw.close();

         }

}

3. 使用字符转换流进行操作数据的时候:字节流+编码格式

 在书写代码名称非常长,Java提供了以中更简单的类:便捷类:

 字符转换输入流:InputStreamReader----->FileReader

 FileReder(String fileName)

 字符转换输出流:OutputStreamWriter---->FileWriter

 FileWriter(String fileName)

 例:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中 使用字符流进行读写操作

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

public class CopyDemo {

         publicstatic void main(String[] args) throws IOException {

//               //创建字符转换输入流对象

//               InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));

//               //封装目的地

//               OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"));

//               //一次读取一个字符数组

//               char []chs = new char[1024];

//               int len = 0;

//               while((len = isr.read(chs)) != -1) {

//                         //写数据:

//                         osw.write(chs,0, len);

//                         //刷新流

//                         osw.flush();

//               }

//               //释放资源

//               isr.close();

//               osw.close();

                   //上面代码书写太长,使用便捷类

                   //数据源:a.txt---->字符流读数据:InputStreamReader------>便捷类:FileReader

                   //目的地:b.txt---->字符流写数据:OutputStreamWriter----->便捷类:FileWriter

                   //1)封装数据源和目的地

                   FileReader fr = new FileReader("a.txt");

                   FileWriter fw = new FileWriter("b.txt");

                   //一次读取一个字符数组

                   char []chs = new char[1024];

                   int len = 0;

                   while((len = fr.read(chs)) != -1) {

                            fw.write(chs,0, len);

                            fw.flush();

                   }

                   //释放资源

                   fw.close();

                   fr.close();

         }

}

4. 关于字符输出流写数据的方法:

  public void write(int c):写单个字符

  public void write(char[] cbuf):写一个字符数组

  public abstract void write(char[] cbuf,int off,int len):写入字符数组的一部分

  public void write(String str):写字符串

  public void write(String str, int off,int len):写字符串的一部分

5. 字符流为了提高读写速度,Java就提供了一个字符缓冲流的类:

  BufferedReader:字符缓冲输入流

   BufferedWriter:字符缓冲输出流

   将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

   可以指定缓冲区的大小,或者接受默认的大小

构造方式:

                         publicBufferedWriter(Writer out):创建默认缓冲区大小的一个字符缓冲输出流

 

例:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class BufferedReaderDemo {

         publicstatic void main(String[] args) throws IOException {

//               BufferedWriter bw = new BufferedWriter(new FileWriter("abc.txt"));

//               //写数据

//               bw.write("hello");

//               bw.write("world");

//               bw.write("Javaweb");

//               //刷新流

//               bw.flush();

//               //关闭资源

//               bw.close();

                   //读数据

                   BufferedReader br = new BufferedReader(new FileReader("abc.txt"));

                   //方式1:一次读取一个字符

                   //int ch = 0;

                   //while ((ch = br.read()) != -1) {

                   //System.out.print((char) ch);

                   //}

                   //方式2:一次读取一个字符数组

                   char []chs = new char[1024];

                   int len = 0;

                   while((len = br.read(chs)) != -1) {

                            System.out.println(newString(chs, 0, len));

                   }

                   //关闭资源

                   br.close();

         }

}

6. 字符缓冲输入流的特有功能:

 BufferedWriter:

                public void newLine():写入一个换行符号

 BufferReader:

                public String readLine():一次读取一行

例:

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class BufferedDemo {

         publicstatic void main(String[] args) throws IOException {

                   Write();

                   Read();

         }

         privatestatic void Read() throws IOException {

                   BufferedReaderbr = new BufferedReader(new FileReader("abc.txt"));

                   //使用循环,当数据读取完毕,如果返回值是null,说明已经读完了

                  String line = null;

                   while((line = br.readLine()) != null) {

                            System.out.println(line);

                   }

                   //释放资源

                   br.close();

         }

         privatestatic void Write() throws IOException {

                   BufferedWriterbw = new BufferedWriter(new FileWriter("abc.txt"));

                   //写数据

                   for(int x = 0; x < 5; x++) {

                            bw.write(x+" "+"hello javaweb!" );

                            //没有使用这个方法之前:需要写入换行符号

                            //bw.write("\r\n") ;

                            //使用特有功能

                            bw.newLine();

                            //刷新该流

                            bw.flush();

                   }

                   //释放资源

                   bw.close();

         }

}

7. 使用IO流的形式读数据

BufferedReadr进行包装

 InputStream is = System.in;//标准输入流

使用is对象能不能一次读取一个数据呢?

不能使用它进行读取数据,BufferedReader可以

 BufferedReader br = newBufferedReader(is);

字符缓冲输入流只能针对字符输入流进行操作,不能针对字节流进行操作

需要将标准输入流转换成字符输入流:InputStreamReader(InputStream in)

创建字符转换输入流对象

InputStreamReader isr = new InputStreamReader(is) ;

创建字符缓冲输入流对象

BufferedReader br = new BufferedReader(isr) ;

一步走

BufferedReader br = new BufferedReader(newInputStreamReader(System.in));

例:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.Scanner;

public classBufferedReaderDemo2 {

    public static void main(String[] args) throws IOException {

        //运用Scanner

//      Scannersc = new Scanner(System.in);

//      System.out.println("请输入一个整数:");

//      int i = sc.nextInt();

//      System.out.println("你输入的整数是:" + i);

        // 使用IO流的形式读数据

        BufferedReaderbr = new BufferedReader(newInputStreamReader(System.in));

        System.out.println("请输入一个整数:");

        Stringstr= br.readLine();// 返回值是一个字符串

        int i = Integer.parseInt(str);

        System.out.println("你输入的整数是:" + i);

    }

}

Day19

1. 数据流

DataOutputStream和DataInputStream

都属于数据流:可以针对Java基本数据类型的数据进行读写操作

DataOutputStream构造方法

public DataOutputStream(OutputStream out)

例:

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class DataStreamDemo {     

         publicstatic void main(String[] args) throws IOException {             

//               write();             

                   read();

         }

         //读数据

         privatestatic void read() throws IOException {

                   //创建数据输入流对象

                   DataInputStream dis = new DataInputStream(new FileInputStream("ab.txt"));  

                   //读数据

                   byte b = dis.readByte();

                   int i = dis.readInt();

                   short s = dis.readShort();

                   long l = dis.readLong();

                   char c = dis.readChar();

                   boolean flag = dis.readBoolean();

                   float f = dis.readFloat();

                   double d = dis.readDouble();  

                   //释放资源

                   dis.close();                

             System.out.println(b);

                   System.out.println(i);

                   System.out.println(s);

                   System.out.println(l);

                   System.out.println(c);

                   System.out.println(flag);

                   System.out.println(f);

                   System.out.println(d);

         }

         //写数据

         privatestatic void write() throws IOException {

                   //创建数据输出流对象

                   DataOutputStream dos = new DataOutputStream(new FileOutputStream("ab.txt"));

                   //写数据

                   dos.writeByte(24);

                   dos.writeInt(50);

                   dos.writeShort(120);

                   dos.writeLong(1000000L);

                   dos.writeChar('A');

                   dos.writeBoolean(true);

                   dos.writeFloat(15.36F);

                   dos.writeDouble(34.23);         

                   //释放资源

                   dos.close();

         }

}

2. ByteArrayInputStream和ByteArrayOutStream

内存操作流:针对内存的数据进行操作的,程序一结束,这些内存中的数据就消失掉了!

特点:针对小文件进行操作(聊天室项目中使用它进行发送文件)

ByteArrayOutputStream:

public ByteArrayOutputStream():创建默认的缓冲区大小的内存操作输出流(单位是字节)

成员方法:

public byte[] toByteArray()创建一个新分配的 byte数组(将内存操作输出流对象转换成字节数组)

void reset():重置内存操作输出流

ByteArrayInputStream:内存操作输入流:

public ByteArrayInputStream(byte[] buf):参数数一个字节数组(缓冲数组)

内存操作流:查看其释放流对象的源码:

public void close() throws IOException {}

并没有具体的关闭流对象,所以此流对象可以不关闭

例:

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

public class ByteArrayStreamDemo {

         publicstatic void main(String[] args) {

                   ByteArrayOutputStream baos = new ByteArrayOutputStream();

                   for(int i = 0; i < 5; i++) {

                            System.out.println(("Hello"+ i).getBytes());                    

                            //关闭资源

//                         baos.close();//并没有具体的关闭流对象,所以此流对象可以不关闭

                            //将内存操作输出流对象转换成字节数组

                            //public byte[] toByteArray()创建一个新分配的 byte数组(将内存操作输出流对象转换成字节数组)

                            byte []buffer = baos.toByteArray();

                            //创建内存操作输入流对象

                            ByteArrayInputStream bais = new ByteArrayInputStream(buffer);

                            //一次读取一个字节

                            int bys= 0;

                            while((bys= bais.read()) != -1) {

                                     System.out.print((char)bys);

                            }

                            //关闭资源

                            //bais.close();

                   }

         }

}

3. 打印流:

字节打印流:PrintStream

字符打印流:PrintWriter

打印流特点:

1)在复制文件的,打印流不能操作数据源,只能操作目的地的数据(只能输出数据)

2)打印流可以有自动刷新的功能

3)打印流可以直接针对文本文件进行操作:

什么情况下是直接可以针对文本文件进行操作?

查API的时候,看流中构造方法,只要构造方法的参数有File类或者是String类型,都可以针对文本文件进行操作

比如:FileInputStream FileOutputStream  FileReader  FileWriter

PrintWriter:

构造方法:

public PrintWriter(String fileName)

import java.io.IOException;

import java.io.PrintWriter;

public class PrintWriterDemo {

         publicstatic void main(String[] args) throws IOException {

                   //创建字符打印流对象

                   PrintWriter pw = new PrintWriter("pw.txt");

                   //写数据

                   pw.write("Hello");

                   pw.write("world");

                   pw.write("Javaweb!");

                   //刷新

                   pw.flush();

                   //释放资源

                   pw.close();

         }

}

4. PrintWriter:有自动刷新功能:

public PrintWriter(Writer out,booleanautoFlush)

第二个参数指定为true,则启动自动刷新

 PrintWriter pw = new PrintWriter(newFileWriter("pw.txt"),true) ;

加入自动刷新功能并且在写数据的时候,使用println():换行

println("hello")

相当于: pw.write("");

pw.newLine();

pw.flush();

例:

import java.io.FileWriter;

import java.io.IOException;

import java.io.PrintWriter;

public class PrintWriterDemo2 {

         publicstatic void main(String[] args) throws IOException {

         //创建字符打印流对象

         PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);// 启动自动刷新功能

         //写数据

         pw.write("hello");

         pw.write("world");

         pw.write("javaweb");//写入在一行

         //使用println

         pw.println("hello");

         pw.println("world");

         pw.println("javaweb");//写入在三行

         //关闭流资源

         pw.close();

         }

}

5. 复制文件

需求:将当前项目下的PrintWriterDemo.java中的内容复制到当前项目下Copy.java文件中

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.PrintWriter;

public class CopyFileDemo {

         publicstatic void main(String[] args) throws IOException {

//               //封装数据源

//               BufferedReader br = new BufferedReader(new FileReader("PrintWriterDemo.java"));

//               //封装目的地

//               BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));

//               //使用BufferedReader中的特有功能读写操作

//               String line = null;

//               while((line = br.readLine()) != null) {

//                         //写数据

//                         bw.write(line);

//                         //换行

//                         bw.newLine();

//                         //刷新流

//                         bw.flush();

//               }

//               //释放资源

//               bw.close();

//               br.close();

                   //改进

                   //封装数据源

                   BufferedReader br = new BufferedReader(new FileReader("PrintWriterDemo.java"));

                   //封装目的地

                   //创建字符打印流对象,并且启动自动刷新功能

                   PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);

                   //读写操作

                   String line = null;

                   while((line = br.readLine()) != null) {

                            //写数据

                            pw.println(line);

                   }

                   //关闭资源

                   pw.close();

                   br.close();

         }

}

6. 标准输入和输出流

System类中有两个字段:

In:----->InputStream is = System.in ;

Out:----->PrintStream ps = System.out ;

System.out.println();

import java.io.PrintStream;

public class SystemOutDemo {        

         publicstatic void main(String[] args) {             

                   //经常使用输出语句

                   System.out.println("hello");

                   System.out.println("world");          

                   //字节打印流

                   PrintStream ps = System.out ;                  

                   //字节打印流调用PrintStream类中的方法

                   ps.println("javaweb");//打印一个字符串数据并且终止当前行

                   ps.println("javaweb");            

         }

}

7. 使用BufferedReader完成录入数据:

使该流封装字符转换输入流,然后使用字符转换输入流封装字节流

按照上述方式,将BufferedWriter层层封装标准输出流,将数据打印控制台

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.OutputStreamWriter;

public class SystemOutDemo2 {

         publicstatic void main(String[] args) {

                    //写入一个分隔符:newLine()是BufferedWriter类中的方法

                    // BufferedWriter bw = new BufferedWriter(ps);

                    //将字节打印流转换成字符流OutputStreamWriter osw = new OutputStreamWriter(ps) ;

                    //创建字符缓冲输出流对象BufferedWriter bw = new BufferedWriter(osw) ;

                   BufferedWriter bw = null;

                   try{

                            bw= new BufferedWriter(new OutputStreamWriter(System.out));

                            //写数据

                            bw.write("hello");

                            bw.newLine();

                            bw.write("world");

                            bw.newLine();

                            bw.write("Javaweb");

                            bw.newLine();

                            //刷新

                            bw.flush();

                   }catch (IOException e) {

                            e.printStackTrace();

                   }finally {

                            //对流对象进行判断

                            if(bw != null) {

                                     try{

                                               bw.close();

                                     }catch (IOException e) {

                                               e.printStackTrace();

                                     }

                            }

                   }

         }

}

8.RandomAccessFile

RandomAccessFile:随机访问流:此类的实例支持对随机访问文件的读取和写入

不是实际意义上的流,因为它继承自Object类

常用的构造方法:

public RandomAccessFile(String name, Stringmode)

参数一:指定该文件的路径

参数二:指定的一种模式:常用的模式:"rw",这种模式是可以读也可以写

例:

import java.io.IOException;

import java.io.RandomAccessFile;

public class RandomAccessFileDemo {

   public static void main(String[] args) throws IOException {

//               write();

             read();

         }

         privatestatic void read() throws  IOException {

                   RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");

             //读数据      

             byte b = raf.readByte();

             System.out.println(b);

             //public long getFilePointer():返回此文件中的当前偏移量文件开头的偏移量(以字节为单位)

             System.out.println("getFilePointer:"+raf.getFilePointer());

             char ch = raf.readChar();

                   System.out.println(ch);

                   String str = raf.readUTF();

                   System.out.println(str);

         }

   //写数据

         privatestatic void write() throws IOException {

                   //创建访问流对象

             RandomAccessFile raf = newRandomAccessFile("raf.txt","rw");

             raf.writeByte(50);

             raf.writeChar('z');

             raf.writeUTF("我爱中国");

             //关闭资源

             raf.close();

         }

}

9. SequenceInputStream

1)SequenceInputStream:合并流(读数据):表示其他输入流的逻辑串联

合并流在复制文件的时候,只能操作数据源,不能操作目的地

例:

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.SequenceInputStream;

 

public class SequenceInputStreamDemo {

  public static void main(String[] args) throws IOException {

            //封装两个java文件

         InputStream is1 = new FileInputStream("RandomAccessFileDemo.java");

         InputStream is2 = new FileInputStream("FileInputStreamDemo.java");

         //创建合并流对象

         SequenceInputStream sis = new SequenceInputStream(is1,is2);

         //封装目的地

         BufferedOutputStream os=new BufferedOutputStream(new FileOutputStream("twoCopy.java"));

         //一次一个字节数组

         byte [] bys=new byte[1024];

         int len=0;

         while((len=sis.read(bys))!=-1){

                   os.write(bys,0,len);

                   os.flush();

         }

         sis.close();

         os.close();

}

}

2) SequenceInputStream的另一种构造方法:复制多个文件

 public SequenceInputStream(Enumeration<? extends InputStream> e)

Vector集合中的特有功能:

public Enumeration<E> elements()

例如:

之前的操作:

a.txt--->b.txt

c.txt--->d.txt

e.txt--->f.txt

现在:a.txt+b.txt+e.txt---->f.txt

例:

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.SequenceInputStream;

import java.util.Enumeration;

import java.util.Vector;

public class SequenceInputStreamDemo2 {

         publicstatic void main(String[] args) throws IOException {

                   //创建一个Vector集合,泛型数据类型为<InputStream>

                   Vector<InputStream> v = new Vector<InputStream>();

                   //封装三个java文件

                   InputStream is1 = new FileInputStream("RandomAccessFileDemo.java");

                   InputStream is2 = new FileInputStream("FileInputStreamDemo.java");

                   InputStream is3 = new FileInputStream("twoCopy.java");

                   //添加到集合中

                   v.add(is1);

                   v.add(is2);

                   v.add(is3);

                   //调用特有功能public Enumeration<E> elements()

                   Enumeration<InputStream>e = v.elements();

                   //创建合并流对象

                   SequenceInputStreamsis = new SequenceInputStream(e);

                   //封装目的地

                   BufferedOutputStream bos = new BufferedOutputStream(

                                     newFileOutputStream("Copy.java"));

                   byte []bys = new byte[1024];

                   int len = 0;

                   while((len = sis.read(bys))!=-1) {

                            //写数据

                            bos.write(bys,0, len);

                            bos.flush();

                   }

                   //释放资源

                   sis.close();

                   bos.close();

         }

}

10. 序列化流:将对象像流的方式或者网络传输中的数据写数据.对象---->流数据:ObjectOutputStream

反序列化:将流数据或者网络传输中的流数据读取出来.流数据---->还原成对象:ObjectInputStream

ObjectOutputStream中的成员方法:

public final void writeObject(Object obj):将obj对象写入到当前的序列化流中

ObjectInputStream中的成员方法:

public final Object readObject():从当前反序列化流中读取一个对象

Serializeable:序列化接口

类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化,如果自定义一个类没有实现这个接口,就不能使用

序列化或者是反序列化!如果一个接口中没有字段,没有构造方法,没有成员方法,叫做标记接口

如果一个类实现了标记接口:Serializable,那么对应的该类加载的时候,会产生一个ID

如果启用序列化功能,那么必须实现一个接口:Serializable

序列化和反序列化版本号不一致,会出现InvalidClassException

解决这个异常两种方案:

1)要么改动当前某个类中的数据之后,然后重新序列化和反序列化

这种做法不符合实际要求,在实际开发中,可能直接读数据:将流数据--->还原成对象

2)发现黄色警告线,点击它:生成一个固定ID

注意事项:

比如一个类中有很多成员变量,并不想让一些成员变量被序列化,Java提供了一个关键字:

transient:不用被序列化的时候用它修饰

序列化和反序列化考点:

1)将对象--->流数据或者流数据--->对象,该对象所在的类要实现一个标记接口:serializable          

2)序列化和反序列化生产的版本Id不一致的时候,会出现异常,所以使用生产随机ID或者固定ID解决

3)transient:修饰的变量不会被序列化

例:

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class ObjectStreamDemo {

         publicstatic void main(String[] args) throws Exception {

//               write();

                   read();

         }

         //读数据

         privatestatic void read() throws IOException, ClassNotFoundException {

                   //创建一个反序列化流对象

                   ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));

                   //使用反序列化

                   Object obj = ois.readObject();

                   //关闭资源

                   ois.close();

                   System.out.println(obj);

         }

         //序列化

         privatestatic void write() throws IOException {

                   //创建一个对象

                   Person p = new Person("张三", 22);

                   //创建一个序列化流对象

                   ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

                                     "oos.txt"));

                   //写数据

                   oos.writeObject(p);

                   //释放资源

                   oos.close();

         }

}

 

import java.io.Serializable;

public class Person implements Serializable{

         privatestatic final long serialVersionUID = 1L;

         //生成一个ID

         private String name;

         private int age;

         publicPerson() {

                   super();

         }

         publicPerson(String name, int age) {

                   super();

                   this.name= name;

                   this.age= age;

         }

         publicString getName() {

                   returnname;

         }

         publicvoid setName(String name) {

                   this.name= name;

         }

         publicint getAge() {

                   returnage;

         }

         publicvoid setAge(int age) {

                   this.age= age;

         }

         @Override

         publicString toString() {

                   return"Person [name=" + name + ", age=" + age + "]";

         }

}

11. Properties

1)Properties:属性集合类,该类继承自Hashtable<K,V>,该类属于Map集合

Properties 类表示了一个持久的属性集。

Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串(一般情况:它用作配置文件去使用,MySQL或者Oracle中用它做配置文件)

构造方法:

 public Properties():创建一个空属性列表

例:

import java.util.Properties;

import java.util.Set;

public class PropertiesDemo {

         publicstatic void main(String[] args) {

                   //创建属性集合类对象

                   Properties prop = new Properties();

                   //添加元素

                   prop.put("张三","45");

                   prop.put("李四","25");

                   prop.put("王五","40");

                   prop.put("赵六","30");

                   //遍历集合

                   //获取所有的键的集合

                   Set<Object> keySet = prop.keySet();

                   //增强for遍历

                   for(Object key : keySet) {

                            System.out.println(key+ "=====" + prop.get(key));

                   }

         }

}

2) 属性集合类:Properties有自己的遍历和添加元素的功能

给属性列表中添加元素:

public Object setProperty(String key,Stringvalue)

public Set<String>stringPropertyNames():获取当前属性列表中所有的键的集合,键值都是String类型

public String getProperty(String key)用指定的键在此属性列表中搜索属性值

例:

import java.util.Properties;

import java.util.Set;

public class PropertiesDemo2 {

         publicstatic void main(String[] args) {

                   //创建属性集合类对象

                   Properties prop = new Properties();

                   //添加元素

                   //public Object setProperty(String key,String value)

                   prop.setProperty("张三","25");

                   prop.setProperty("李四","35");

                   prop.setProperty("王五","45");

                   prop.setProperty("赵六","40");

                   //遍历属性列表public Set<String> stringPropertyNames()

                   Set<String> keySet = prop.stringPropertyNames();

                   for(String key : keySet) {

                            System.out.println(key+ "====" + prop.getProperty(key));

                   }

         }

}

12. Properties 可保存在流中或从流中加载。

  将文件中的数据加载到属性集合中:public void load(Reader reader)

  将属性集合中的数据保存到文件中:public void store(Writer writer,String comments)

第二个参数:comments:对当前属性列表的描述

例:

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.util.Properties;

public class PropertiesDemo3 {

         publicstatic void main(String[] args) throws IOException {

//               mySave();

                   myLoad();

         }

         privatestatic void myLoad() throws IOException {

                   //创建属性集合对象

                   Properties pro = new Properties();

                   //创建字符输入流对象

                   FileReader fr = new FileReader("Person.txt");

                   //调用方法

                   pro.load(fr);

                   fr.close();

                   //显示输出

                   System.out.println(pro);

         }

         privatestatic void mySave() throws IOException {

                   //创建属性集和对象

                   Properties pro = new Properties();

                   //添加元素

                   pro.setProperty("张三","30");

                   pro.setProperty("李四","40");

                   pro.setProperty("王五","50");

                   //把属性集合中数据保存到文件中

                  FileWriter fw = newFileWriter("Person.txt");

                   //调用方法

                   pro.store(fw,"names content");

                   fw.close();

         }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值