IO流

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO流相关的知识,希望对你有一定的参考价值。

IO

 

1 输入流/输出流

IO流用来处理设备之间的数据传输

JAVA对数据的操作是通过流的方式

JAVA用于操作流的对象都在IO包中

流按操作数据分为两种,字节流和字符流

流按方向分为两种:输出流和输入流

 

从内存到外围设备称为输出(写)  从外围设备到内存称为输入(读)

 

2字符流/字节流

字节流

 

字符流:字节流读取文字数据后,不直接操作而是先查指定的编码表,获取对应的文字,在对这个文字进行操作。简单说,字符流就是字节流+编码表。

 

3 字符流----FileWriter

 

字节流的两个顶层父类

1 InputStrean 2 OutputStream

 

字符流的两个顶层父类

1 Reader 2 Writer

 

 

这些体系的子类都以父类名作为前缀

而且子类名的前缀就是该对象的功能

 

就从熟悉的文字开始

 

//需求:将一些文字存储到硬盘一个恩建中

操作文字数据,建议优先考虑字符流,而且要将数据从内存写到硬盘上,就要使用字符流中的输出流 Writer

 

硬盘的数据体现是文件所以选择FileWriter

 

 

package IO;

 

import java.io.FileWriter;

import java.io.IOException;

 

public class FileWritterDemo {

 

private static final String LINE_SEPARATOR=System.getProperty("line.separator");

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

   

   //创建一个可以往文件中写入字符数据的字符输出流对象

   /*

    * 既然是往一个文件中写入文字数据,那么在创建文件时,必须明确该文件(用于存储数据的目的地)

    *

    *如果文件不存在,则会自动创建

    *如果文件存在,则会被覆盖

    */

 

   FileWriter fw=new FileWriter("demo.txt",true);

   

   /*

    * 调用Writer对象中的write方法,写入数据

    *

    *其实数据写入到临时存储缓冲区中

    *

    *

    *如果构造函数中加入true可以实现对文件进行续写

    *

    */

   fw.write("abcdev"+LINE_SEPARATOR+"hahaha");

       fw.write("123");

    /*

     * 进行刷新,将数据直接写入到目的地

     */

   fw.flush();

   

   /*关闭此流 释放资源*/

   fw.close();

 

   }   

}

 

 

 

 

4 IOException处理

package IO;

 

import java.io.FileWriter;

import java.io.IOException;

 

public class IOExceptionDemo {

 

private static final String LINE_SEPARATOR=System.getProperty("line.separator");

    public static void main(String[] args) {

     FileWriter fw=null;

     try {

     fw=new FileWriter("k:\\demo.txt");

      

      fw.write("abcdev"+LINE_SEPARATOR+"hahaha");

      

      fw.close();

} catch (IOException e) {

System.out.println(e.toString());

}

     finally

     {   if(fw!=null)

     try {

fw.close();

} catch (IOException e) {

throw new RuntimeException("关闭失败");

}

     }

}

}

 

 

 

 

5 字符读取流---读取方式一

 

package IO;

 

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

 

public class FileReaderDemo {

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

 

  /*

   *

   *1 创建读取字符数据的流对象

   *

   *在创建读取流对象时,必须要明确被读取的文件,一定要确定文件是存在的

   *

   *用一个读取流关联一个已存在文件

   */

  

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

  

  //Reader中的read方法读取字符

  int ch=fr.read();

  System.out.println(ch);

  ch=fr.read();

  System.out.println((char)ch);

  ch=fr.read();

  System.out.println(ch);

  ch=fr.read();

  System.out.println(ch);

  /*

   *

   * while((ch=fr.read())!=-1)

   * {

   *   system.println((char)ch);

   * }

   *

   *

   *

   *

   */

  

  fr.close();

  

  

}

}

 

 

 

6 字符读取方式2

package IO;

 

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

 

public class FileReaderDemo2 {

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

 

  /*

   *

   *1 创建读取字符数据的流对象

   *

   *在创建读取流对象时,必须要明确被读取的文件,一定要确定文件是存在的

   *

   *用一个读取流关联一个已存在文件

   */

  

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

  

     /*

      *使用read(char[])读取文本文件数据

      */

/*

 * 创建字符数组

 */

  char []buf=new char[3];

  

  int num=fr.read(buf);//将读取的字符存储到数组中

  System.out.println(num+":"+new String(buf,0,num));

  

  int num1=fr.read(buf);//将读取的字符存储到数组中

  System.out.println(num1+":"+buf);

 

     int len=0;

     

         

  

  fr.close();

  

  

}

}

 

 

package IO;

 

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

 

public class FileReadAndWrite {

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

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

   

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

 

         char []buff=new char[1024];

         int len;

         while((len=(fr.read(buff)))!=-1)

         {

          fw.write(buff, 0, len);

          fw.flush();

         }

     if(fr!=null)

         fr.close();

     if(fw!=null)

         fw.close();

       

 

 

 

  

}

   

}

 

 

7字符流缓冲区

 

缓冲区的出现提高了对数据的读写效率。

对应类

  BufferedWriter

  BufferedReader

缓冲区要结合流才可以使用(相当于我们不用自己创建数组)

在流的基础上对流的功能进行了增强

 

 

 

BufferedWriter

package IO;

 

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

 

public class BufferDemo {

    

 

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

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

  

  //为了提高写入的效率,使用了字符流的缓冲区

  //创建了一个字符写入流的缓冲区对象 并和指定要被缓冲的流对象相关联

  

  BufferedWriter bufw=new BufferedWriter(fw);

  

  //使用缓冲区的写入的方法将数据写入缓冲区中

  bufw.write("abcdefswddd");

  bufw.newLine();

  bufw.write("abc");

 

  

  //使用缓冲区的刷新方法将数据刷新到目的地中

  bufw.flush();

  

  //关闭缓冲区   流也会关

  bufw.close();

 

  

}

}

 

 

BufferedReader

package IO;

 

import java.io.BufferedReader;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

 

public class BufferReaderDemo {

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

 

   

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

   

   BufferedReader bufr=new BufferedReader(fr);

       String line=null;

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

   {

   System.out.println(line);

   }

   

   

   bufr.close();

   

}

}

 

 

 

BufferedReaderreadline方法 和BufferedWriternewLine方法较为常用

 

8字节流基本演示

package IO;

 

import java.io.FileInputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

 

public class FileReadAndWrite {

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

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

   int ch;

   /*while((ch= fis.read())!=-1)

   {

   System.out.println((char)ch);

   }

   */

   byte []buf=new byte[1024];

    int len;

    while((len=fis.read(buf))!=-1)

    {

     System.out.println(new String(buf,0,len));

    }

   

  

}

   

}

 

 

不需要使用flush方法 具体使用请查看API

 

9键盘录入

package myNewIo;

 

import java.io.IOException;

import java.io.InputStream;

 

public class KeyBoardDemo {

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

 InputStream in=System.in;

 int ch=in.read();

 System.out.println(ch);

 int ch1=in.read();

 System.out.println(ch1);

}

}

不需要关闭流 (因为它是默认设备)

 

 

10 转换流

 

package myNewIo;

 

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

 

public class TranslateStream {

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

     //字节流

     InputStream in=System.in;

     OutputStream out=System.out;

     //转换流->转成字符流,就能像操作字符一样

     InputStreamReader isr=new InputStreamReader(in);

     OutputStreamWriter osw=new OutputStreamWriter(out);

     //装饰

     BufferedReader bufr=new BufferedReader(isr);

     BufferedWriter bufw=new BufferedWriter(osw);

     String line=null;

         

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

     {   

     if(line.equals("over"))

     {

     break;

     }

     bufw.write(line);

     bufw.newLine();

     bufw.flush();

    

     }

}

 

 

 

}

 

 

11 流操作基本规律

 

之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。

 

想要知道开发时用哪个对象。只要通过四个明确。

 

 

1 明确源和目的

 源:InputStream 或者Reader

 目的 OutputStrean 或者 Writer

 

 

2 明确数据是否是纯文本

源:是纯文本 Reader

InputStream

 

目的 是纯文本:Writer

      否:OutputStream

 

到这里就可以明确需要中具体要用到哪个体系

 

3明确具体的设备

  源设备

  

  硬盘:File

  键盘:System.in

  内存:数组

  网络: socket

 

目的设备:

 

   硬盘 File

   控制台  Systen.out

   内存 数组

   网络 socket

 

4 是否需要额外功能

 

 

12  转换流的编码解码。

字符串用的码表是本地系统用的码表

JAVA内置的码表是UNICODE 字符类型就是这个码表识别的

 

其实FileWriter就等同于 转换流加本地编码表(如果要自己指定编码表,就必须使用转换流指定编码表)

 

 

 

13File

用来将文件或者文件夹封装成对象

方便对文件和文件夹的属性信息进行操作

File对象可以作为作为参数传递给流的构造函数

 

了解File类的常用方法

 

package Fiie;

 

import java.io.File;

 

public class FileDemo {

    public static void main(String[] args) {

  constructorDemo();

}

 

private static void constructorDemo() {

/*

 * 可以将一个已存在的或者不存在的文件或者目录封装成FILE对象

 */

File f1=new File("d:\\a.txt");

File f2=new File("d:\\","a.txt");

 

File f=new File("c:\\");

 

File f3=new File(f,"a.txt");

 

File f4=new File("c:"+File.separator+"abc"+File.separator+"a.txt");

 

 

}

}

 

 

1  * File对象常见方法(文件或者目录操作)

package Fiie;

 

import java.io.File;

import java.text.DateFormat;

import java.util.Date;

 

public class FileDemo1 {

  public static void main(String[] args) {

 

   /* 1获取  

    *    1.1 获取文件名称

    *    1.2 获取文件路径

    *    1.3 获取文件大小

    *    1.4获取文件修改时间

    */

  File file=new File("1.txt");

   String name=file.getName();

   

   String abspath=file.getAbsolutePath();

   

   String path=file.getPath();

   

   long len=file.length();

   

   long time=file.lastModified();

   

   Date date=new Date(time);

  

   DateFormat dateFormat=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);

   String str_time=dateFormat.format(date);

   

   System.out.println("name:"+name);

   

   System.out.println("abspath:"+abspath);

   

   System.out.println("path:"+path);

   

   System.out.println("len:"+len);

   

   System.out.println("time:"+str_time);

 

}

}

 

 

2创建和删除

package Fiie;

 

import java.io.File;

import java.io.IOException;

import java.text.DateFormat;

import java.util.Date;

 

public class FileDemo1 {

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

 

   /*

    * 2 创建和删除

    */

  

  // File f=new File("x.txt");

   //存在则不创建 不存在则创建(与IO流不一样)

   //boolean b=f.createNewFile();//创建

  // System.out.println("b="+b);

   

   //删除

//  boolean b1=f.delete();

 //  System.out.println("b1="+b1);

  

  //创建目录

  File f1=new File("abc");

  boolean b3=f1.mkdir();

  System.out.println("b3="+b3);

  

  //创建多级目录

  File f2=new File("bc\\dd\\ds\\dssw\\d\\s\\dddfa\\ffwas\\ffsa");

  boolean b4=f2.mkdirs();

  System.out.println("b4="+b4);

  f2.delete();  //删除最里面的目录

}

}

 

 

 

3 判断

package Fiie;

 

import java.io.File;

import java.io.IOException;

import java.text.DateFormat;

import java.util.Date;

 

public class FileDemo1 {

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

 

/*

 * 判断

 */

  

  File f=new File("1.txt");

  boolean b=f.exists(); //判断文件是否存在

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

  

  System.out.println(f.isFile());   //要先判断是否存在

  System.out.println(f.isDirectory());

}

}

 

4 重命名

package Fiie;

 

import java.io.File;

import java.io.IOException;

import java.text.DateFormat;

import java.util.Date;

 

public class FileDemo1 {

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

 

 

  /*

   * 重命名 路径一样会改名,路径不一样会剪切

   */  

  File f1=new File("c:\\a.txt");

  File f2=new File("c:\\b.txt");

  f1.renameTo(f2);

  

}

}

 

5 系统根目录和容量空间

package Fiie;

 

import java.io.File;

import java.io.IOException;

import java.text.DateFormat;

import java.util.Date;

 

public class FileDemo1 {

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

 

 

  /*

   * 系统根目录和容量空间

   */  

 File []file=File.listRoots();

 for(File f:file)

 System.out.println(f);

 

 File file1=new File("d:\\");

 System.out.println("getFreeSpace:"+file1.getTotalSpace());

  

}

}

 

6 获取目录内容

package Fiie;

 

import java.io.File;

import java.io.IOException;

import java.text.DateFormat;

import java.util.Date;

 

public class FileDemo1 {

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

 

  File f=new File("e:\\");

  String []names=f.list();

  

  for(String s:names)

  System.out.println(s);

 

  

}

}

 

7获取当前目录内容

package Fiie;

 

import java.io.File;

import java.io.IOException;

import java.text.DateFormat;

import java.util.Date;

 

public class FileDemo1 {

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

/*

 * 获取当前目录下的文件以及文件夹的名称,包含隐藏文件

 * 调用List方法的File对象中封装的必须是目录

 * 否则会发生NullPointerException

 * 如果访问的是系统级目录也会发生空指针异常

 *

 *

 * 如果目录存在 但是没有内容 会返回0长度的数组

 */

  File f=new File("e:\\");

  String []names=f.list();

  

  for(String s:names)

  System.out.println(s);

 

  

}

}

 

8 过滤器(当需要过滤时 寻找对应的接口 并实现方法)

package Fiie;

 

import java.io.File;

 

public class FileDemo {

    public static void main(String[] args) {

  File dir=new File("e:\\javacode\\IO2\\src\\OtherIo");

  

  String []names=dir.list(new FilterByName());

  

  for(String name:names)

  {

  System.out.println(name);

  }

}

 

 

}

 

package Fiie;

 

import java.io.File;

import java.io.FileFilter;

import java.io.FilenameFilter;

 

public class FilterByName implements FilenameFilter {

 

public boolean accept(File dir, String name) {

return name.endsWith(".java");

}

 

 

}

 

还有各种过滤器 需要时查找API

 

 

 

 

9

Properties集合

package Fiie;

 

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.Properties;

import java.util.Set;

 

public class PropertiesDemo {

      /*

       *

       * Map

       *    ----HashTable

       *         ---------Properties

       *      

       *      

       * Properties集合

       *

       * 特点:

       * 1 该集合中的键和值都是字符串类型

       * 2 集合中的数据可以保存到流中,或者从流获取

       *

       * 通常该集合用于操作键值对形式存在的配置文件

       *

       *

       */

/*

 * 集合的存和取

 *

 */

 

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

//propertiesDemo();

//method_demo3();

        method_demo4();

}

 

 

   private static void method_demo4() throws IOException {

   //集合中的数据来自一个文件

   // 必须保证该文件的数据是键值对

   //需要使用读取流

   Properties prop=new Properties();

   

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

   

   //使用load方法

   prop.load(fis);

   

   prop.list(System.out);

   

}

 

 

private static void method_demo3() throws IOException {

           

   

   //创建一个Properties集合

   

   Properties prop=new Properties();

   

 

   

  

   //存入元素

   prop.setProperty("zhangsan","30");

   prop.setProperty("lisi","30");

   prop.setProperty("wangwu","30");

   prop.setProperty("lisi","36");

   

   //想要将这些集合中的字符键值信息持久化存储到文件中

   //需要关联输出流

   FileOutputStream fos=new FileOutputStream("info.txt");

   

   

   //将集合中数据存储到文件中,使用Store方法

   prop.store(fos, "name+age");

   

   fos.close();

}

 

 

public static void propertiesDemo()

   {

   

   //创建一个Properties集合

   

   Properties prop=new Properties();

   

 

   

  

   //存入元素

   prop.setProperty("zhangsan","30");

   prop.setProperty("lisi","30");

   prop.setProperty("wangwu","30");

   prop.setProperty("lisi","36");

   

   

   //取出元素

   

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

   

   for(String name:names)

   {

   

   String value=prop.getProperty(name);

   System.out.println(name+":"+value);

   }

   

   prop.list(System.out);

   

   }

}

 

 

 

 

10 IO包的其它流

 

Print系列也是属于装饰 提供额外功能

 

 

PrintSream

package demo1;

 

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.PrintStream;

 

public class PrintStreamDemo {

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

  /*

   * PrintStream

   * 1 提供了打印方法对多种数据类型值进行打印,并保持数据的表示形式

   * 2 它不抛IOEXCEPTION

   *

   *

   * 构造函数 它接收三种类型的值

   * 1 字符串路径

   * 2 File对象

   * 3 字节输出流

   */

   

   PrintStream out=new PrintStream("print.txt");

   

   out.write(97);

   

   out.print(97);//保持原样 写入

   

   

   out.close();

}

}

 

 

 

PrintWriter

package demo1;

 

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.PrintWriter;

 

public class PrintWriterDemo {

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

/*

 * PrintWriter:字符打印流

 *

 * 构造函数参数

 * 1 字符串路径

 * 2 File对象

 * 3 字节输出流

 * 4 字符输出流

 */

  

  BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

  PrintWriter out=new PrintWriter(System.out);

  

  String line=null;

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

  {

 if("over".equals(line))

 break;

 out.println(line.toUpperCase());

 out.flush();

  }

  out.close();

  bufr.close();

}

}

 

 

11 序列流

package demo1;

 

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Enumeration;

import java.util.Vector;

 

public class SequenceInputStream {

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

   /*

    * 需求:将1.txt 2.txt 3.txt 文件中的数据合并到一个文件中

    *    

    *    

    */

  

  ArrayList<FileInputStream> v=new ArrayList();

  v.add(new FileInputStream("1.txt"));

  v.add(new FileInputStream("2.txt"));

  v.add(new FileInputStream("3.txt"));

  

  Enumeration<FileInputStream>  en=Collections.enumeration(v);

  

  SequenceInputStream sis=new SequenceInputStream(en);

  

  FileOutputStream fos=new FileOutputStream("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();

 

}

}

 

 这个还可以做到文件合并

 

通过以前的流还可以做到文件合并

 

12对象序列化和反序列化

package demo1;

 

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

 

public class ObjectSequenceDemo {

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

   FileOutputStream fos =new FileOutputStream("obj.object");

   

   ObjectOutputStream oos=new ObjectOutputStream(fos);

   

   oos.writeObject(new Person("小李",22));

   

   oos.close();

   fos.close();

   

}

    

}

 

 

 

package demo1;

 

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

 

public class ObjectSequenceDemo {

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

   FileInputStream fis =new FileInputStream ("obj.object");

   

   ObjectInputStream ois=new ObjectInputStream (fis);

   

  Object obj=ois.readObject();

  Person p=(Person)obj;

  System.out.println(p.getAge()+":"+p.getName());

   

   ois.close();

   fis.close();

   

}

    

}

 

 

保证在类文件修改后 仍然可以读取(即保证版本一样 就需要自己定义标记号  

private static final long serialVersionUID

在数据前修饰 translent  可以保证不写入文件

 

 

13随机访问文件

 

package demo1;

 

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.RandomAccessFile;

 

public class RandomAccessDemo {

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

/*

 * RandomAccessFile

 * 一看这个名字,好像不是文件体系的对象

 *

 * 特点:

 * 1 该对象既能读,又能写

 * 2 该对象内部维护了一个byte数组。并通过指针可以操作数组中的元素

 * 3 可以通过getFilePointer方法获取指针的位置,并通过seek方法设置指针位置

 * 4 其实该对象就是将字节输入流和输出流进行了封装

 * 5 该对象的源和目的只能是文件,通过构造函数就可以看出

 */

  

  //使用 RandomAccessFile对象写入一些人员信息。比如姓名和年龄

  writeFile();

  

}

  

  public static void writeFile() throws IOException

  {

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

  

  raf.write("张三".getBytes());

  raf.write(‘);

  

  

  raf.close();

  }

}

至于读 就不说了  这个对象的最大特点就是能更方便的操作数据。(int long byte等等)

 

 

 

14管道流

 

 

 

15 简单的编码解码

String s=”你好”;

Byte []b=s.getbytes(可以指定字符集);

 

以上是关于IO流的主要内容,如果未能解决你的问题,请参考以下文章

IO流之IO流综述

IO异常--缓冲流--转换流--序列化流( IO流2 )

IO流(序列流)

java中的io流都有哪些

java IO流 IO流概述

IO流