io流

本文详细介绍了Java中的IO流概念及分类,包括文件操作类File的使用、常用的IO流类如FileInputStream、FileOutputStream等,并提供了丰富的示例代码,帮助读者理解和掌握如何进行文件的读写操作。
摘要由CSDN通过智能技术生成

第十一章 IO流(输入/输出)

目标:

1. 掌握文件操作类File

2. 理解流的概念、掌握IO流的分类

3. 掌握IO流中常用类

4. 掌握处理流

5. 掌握System对IO流的支持

6. 了解对象流

 

一、  文件操作类File

▲File类常用构造方法

File(File parent, String child) 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

File(String pathname) 通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。

File(String parent, String child) 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。

File(URI uri) 通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。

 

▲File类中两个常量

static String

pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。 Windows  ;

static String

separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。 Windows  \

 

▲File类中常用方法

 boolean

createNewFile() 当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。

 boolean

delete() 删除此抽象路径名表示的文件或目录。

 boolean

exists() 测试此抽象路径名表示的文件或目录是否存在。

String

getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。

String

getName() 返回由此抽象路径名表示的文件或目录的名称。

 String

getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null

String

getPath() 将此抽象路径名转换为一个路径名字符串。

 boolean

isDirectory() 测试此抽象路径名表示的文件是否是一个目录。

 boolean

isFile() 测试此抽象路径名表示的文件是否是一个标准文件。

long

length() 返回由此抽象路径名表示的文件的长度。

 String[]

list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

File[]

listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

boolean

mkdir() 创建此抽象路径名指定的目录。

 

 

案例一:在D盘下面创建文件1.txt

package test_12_9;

import java.io.*;

import javax.swing.JOptionPane;

public class Test1 {

      public static void main(String[] args) {

           File f = new File("D:\\1.txt");

           //最好用File f = newFile("D:"+File.separator+"1.txt");

           if(!f.exists()){//不存在

                 try {

                      f.createNewFile();

                 } catch (IOException e) {

                      // TODO Auto-generated catchblock

                      e.printStackTrace();

                 }

           }else{

                 JOptionPane.showMessageDialog(null, "文件已存在!");

           }

      }

}

注意:为了保证Java程序的跨平台性,做文件操作时最好不要直接用“D:\\1.txt”,因为不同操作系统的路径分隔符不同(eg:windows是\  Linux是/),如果直接使用“D:\\1.txt”那么该程序到Linux平台则无法直接运行,所以最好使用File.separator代替

 

案例二:输出文件的属性

package test_12_9;

import java.io.*;

public class Test2 {

     public static void main(String[] args) {

         File f = new File("D:\\abc\\1.txt");

         System.out.println("f的绝对路径:"+f.getAbsolutePath());

         System.out.println("f的路径:"+f.getPath());

         System.out.println("f的父路径:"+f.getParent());

         System.out.println("f的文件名:"+f.getName());

         System.out.println("f的文件长度:"+f.length());

     }

}

 

案例三:对目录操作,输出指定目录下所有内容

方法一:使用list()

package test_12_9;

import java.io.*;

import javax.swing.JOptionPane;

public class Test3 {

      public static void main(String[] args) {

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

           if(f.isDirectory()){

                 String[] s = f.list();

                 for(int i = 0;i<=s.length-1;i++){

                      System.out.println(s[i]);

                 }

           }else{

                 JOptionPane.showMessageDialog(null, "你指定的不是目录!");

           }

      }

}

 

方法二:使用listFiles()

package test_12_9;

import java.io.*;

import javax.swing.JOptionPane;

public class Test3 {

      public static void main(String[] args) {

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

           if(f.isDirectory()){

                 File[] file = f.listFiles();

                 for(int i = 0;i<=file.length-1;i++){

                      System.out.println(file[i].getName());

                 }

           }else{

                 JOptionPane.showMessageDialog(null, "你指定的不是目录!");

           }

      }

}

 

案例四:对目录操作,输出指定目录下所有文件(注意目录中还有子目录)

package test_12_9;

import java.io.*;

import javax.swing.JOptionPane;

public class Test3 {

      public static void printFile(File f){

           if(f!=null){

                 if(f.isDirectory()){

                      //是目录

                      File[] file =f.listFiles();

                      if(file!=null){

                            for(int i = 0;i<=file.length-1;i++){

                                  printFile(file[i]);

                            }

                      }

                 }else{

                      //是文件

                      System.out.println(f);

                 }

           }

      }

      public static void main(String[] args) {

           File f = new File("D:\\abc");

           printFile(f);

      }

}

 

二、  理解流的概念、掌握IO流的分类

Java中IO流是实现输入输出的基础,它可以完成数据的输入输出操作。

流:数据从数据源(文件)到程序(内存)之间经历的路径

 

IO流分类:

1.       按照数据流动方向:输入流、输出流

输入流:数据从数据源到程序(InputStreamReader)

输出流:数据从程序到数据源(OutputStreamWriter)

 

2.       按照读取的方式分类:字节流、字符流

字节流:读写二进制文件(一次读写一个字节8位二进制)(InputStreamOutputStream)

字符流:读写文本文件(一次读写一个字符16位二进制) (ReaderWriter)

 

3.       按照流的角色分类:节点流、处理流

节点流(低级流):直接连接在数据源上的流

处理流(高级流):包装在节点外面的流

 

三、  IO流中常用类

IO流中抽象基类:

    InputStream(字节输入流)

    OutputStream(字节输出流)

    Reader(字符输入流)

    Writer(字符输出流)

IO流常用类:

FileInputStream文件输入流

 

▲常用构造方法

FileInputStream(File file) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。

FileInputStream(String name) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

 

▲常用方法

 int

read() 从此输入流中读取一个数据字节。

 int

read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。

 

案例一:字节输入流FileInputStream

/**

 * 使用FileInputStream读取G:\abc\1.txt中的内容

 */

package anli;

import java.io.*;

public class Test1 {

    FileInputStream fis ;

    public Test1(){

       try {

           //1.在指定的文件上创建一个流

           fis = new FileInputStream("G:\\abc\\1.txt");

           //2.

           byte[] b = new byte[1024];

           int x = 0;//x保存读取的数据长度

           while((x=fis.read(b))>0){

              String s = new String(b,0,x);//byte数组中的值转化成字符串并输出

              System.out.println(s);

           }

           fis.close();//关闭流

       } catch (Exception e) {

           // TODO: handle exception

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test1 t = new Test1();

    }

}

 

 

FileOutputStream文件输出流

 

▲常用构造方法

FileOutputStream(File file)  创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。

FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。

 

▲常用方法

 void

write(byte[] b)b.length 个字节从指定 byte 数组写入此文件输出流中。

 void

write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

 void

write(int b) 将指定字节写入此文件输出流。

 

案例二:字节输出流FileOutputStream

/**

 * 使用FileOutputStreamG:\abc\2.txt中写入内容

 */

package anli;

import java.io.*;

public class Test2 {

    FileOutputStream fos;

    public Test2(){

       try {

           //1.在指定文件上创建输出流

           fos = new FileOutputStream("G:\\abc\\2.txt");

           //2.写入数据

           String s = "静夜思\r\n床前明月光\r\n疑是地上霜\r\n";

           byte[] b = s.getBytes();

           fos.write(b);

           //3.关闭流

           fos.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test2 t = new Test2();

    }

}

 

案例三:文件拷贝(字节流可以拷贝任何文件 包括图片、视频…)

/**

 * 使用FileInputStreamFileOutputStream完成文件拷贝

 */

package anli;

import java.io.*;

public class Test3 {

    FileInputStream fis;

    FileOutputStream fos;

    public Test3(){

       try {

           //1.创建流

           fis = new FileInputStream("G:\\abc\\1.txt");

           fos = new FileOutputStream("G:\\abc\\2.txt");

           //2.开始读、写

           byte[] b = new byte[1024];

           int x = 0;

           while((x=fis.read(b))>0){//

              fos.write(b, 0, x);//

           }

           //3.关闭流

           fos.close();

           fis.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test3 t = new Test3();

    }

}

 

FileReader文件输入流、字符流

 

▲常用构造方法

FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。

FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。

 

▲常用方法

 int

read() 读取单个字符。 

 int

read(char[] cbuf, int offset, int length) 将字符读入数组中的某一部分。

 

案例四:字符输入流FileReader

/**

 * 使用FileReader读取G:\abc\1.txt中的内容

 */

package anli;

import java.io.*;

public class Test4 {

    FileReader fr ;

    public Test4(){

       try {

           //1.在指定的文件上创建一个流

           fr = new FileReader("G:\\abc\\1.txt");

           //2.

           char[] c = new char[1024];

           int x = 0;//x保存读取的数据长度

           while((x=fr.read(c))>0){

              String s = new String(c,0,x);//byte数组中的值转化成字符串并输出

              System.out.println(s);

           }

           fr.close();//关闭流

       } catch (Exception e) {

           // TODO: handle exception

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test4 t = new Test4();

    }

}

FileWriter文件输出流、字符流

 

▲常用构造方法

FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象。

FileWriter(File file, boolean append) 根据给定的 File 对象构造一个 FileWriter 对象。

FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。

FileWriter(String fileName, boolean append) 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

 

▲常用方法

abstract  void

flush() 刷新该流的缓冲。

 void

write(char[] cbuf) 写入字符数组。

abstract  void

write(char[] cbuf, int off, int len) 写入字符数组的某一部分。

 void

write(int c) 写入单个字符。

 void

write(String str) 写入字符串。

 void

write(String str, int off, int len) 写入字符串的某一部分。

 

案例五:字符输出流FileWriter

/**

 * 使用FileWriterG:\abc\2.txt中写入内容

 */

package anli;

import java.io.*;

public class Test5 {

    FileWriter fw;

    public Test5(){

       try {

           //1.在指定文件上创建输出流

           fw = new FileWriter("G:\\abc\\2.txt");

           //2.写入数据

           fw.write("静夜思\r\n床前明月光\r\n疑是地上霜\r\n");

           //3.关闭流

           fw.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test5 t = new Test5();

    }

}

 

 

案例六:文件拷贝(字符流只能拷贝文本文件)

/**

 * 使用FileReaderFileWriter完成文件拷贝

 */

package anli;

import java.io.*;

public class Test6 {

    FileReader fr;

    FileWriter fw;

    public Test6(){

       try {

           //1.创建流

           fr = new FileReader("G:\\abc\\1.txt");

           fw = new FileWriter("G:\\abc\\2.txt");

           //2.开始读、写

           char[] c = new char[1024];

           int x = 0;

           while((x=fr.read(c))>0){//

              fw.write(c, 0, x);//

           }

           //3.关闭流

           fw.close();

           fr.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test6 t = new Test6();

    }

}

总结:

1.  拷贝文件时,字节流可以拷贝任何文件,字符流只能拷贝文本文件

2.  读取文本文件时,只能使用字符流

 

 

四、  处理流

一般情况下,节点流可以完成任务,但是在有些特殊情况下,节点流无法满足要求,此时可以考虑使用处理流。使用处理流可以方便达到目的. 常用处理流:

1.        打印流:PrintStreamPrintWriter(常用)

2.        缓冲流:BufferedReader

3.        转换流:InputStreamReader

 

★打印流:           

案例一: PrintStream

/**

 * PrintStream 打印流可以包装OutputStream

 */

package test6_8;

import java.io.*;

public class Test1 {

    FileOutputStream fos;

    PrintStream ps;

    public Test1(){

       try {

           //1.创建流对象

           fos = new FileOutputStream("G:\\abc\\1.txt");//1.txt上创建输出流

           ps = new PrintStream(fos);//fos流包装成ps

           //2.写数据

           ps.println("你好!");

           ps.println("大家好!");

           ps.print("才是真的好!");

           //3.关闭流

           ps.close();

           fos.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test1 t = new Test1();

    }

}

 

 

案例二: PrintWriter

/**

 * PrintWriter 打印流可以包装OutputStreamWriter

 */

package test6_8;

import java.io.*;

public class Test2 {

    FileWriter fw;

    PrintWriter pw;

    public Test2(){

       try {

           //1.创建流

           fw = new FileWriter("G:\\abc\\2.txt",true);//2.txt上创建流

           pw = new PrintWriter(fw,true);//fw包装到pw true自动刷新

           //2.写数据

           pw.println("Hello Wolrd!");

           pw.println("你好!");

           pw.println("Wlecom tokaifeng!");

           //3.关闭流

           pw.close();

           fw.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test2 t = new Test2();

    }

}

★缓冲流:           

案例一:BufferedReader

/**

 * BufferedReader缓冲流包装Reader

 */

package test6_8;

import java.io.*;

public class Test3 {

    FileReader fr;

    BufferedReader br;

    public Test3(){

       try {

           //1.创建流对象

           fr = new FileReader("G:\\abc\\2.txt");

           br = new BufferedReader(fr);

           //2.读数据

           String s;

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

              System.out.println(s);

           }

           //3.关闭流

           br.close();

           fr.close();

       } catch (Exception e) {

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test3 t = new Test3();

    }

}

 

★转换流:            InputStreamReader

/**

 * InputStreamReader是字节流通向字符流的桥梁

 */

package test6_8;

import java.io.*;

public class Test4 {

    FileInputStream fis ;

    InputStreamReader isr;

    public Test4(){

       try {

           //1.在指定的文件上创建一个流

           fis = new FileInputStream("G:\\abc\\1.txt");

           isr = new InputStreamReader(fis);//fis包装成InputStreamReader字符流,可以正常读写文本文件

           //2.

           char[] c = new char[1024];

           int x = 0;//x保存读取的数据长度

           while((x=isr.read(c))>0){

              String s = new String(c,0,x);//byte数组中的值转化成字符串并输出

              System.out.println(s);

           }

           isr.close();

           fis.close();//关闭流

       } catch (Exception e) {

           // TODO: handle exception

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test4 t = new Test4();

    }

}

 

 

综合案例一:万能拷贝

package test6_9;

import java.io.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class MyCopy extends JFrame implements ActionListener{

    //1.定义组件

    JLabel title,l1,l2;

    JTextField jtf1,jtf2;

    JButton b1,b2;

    JPanel jp1,jp2,jp3;

    public MyCopy(){

       //2.初始化组件

       title = new JLabel("万能拷贝器",JLabel.CENTER);

       l1 = new JLabel("原始文件地址:");

       l2 = new JLabel("目标文件地址:");

       jtf1 = new JTextField(20);

        jtf2 = new JTextField(20);

       b1 = new JButton("拷贝");

       b2 = new JButton("取消");

       jp1 = new JPanel();

       jp2 = new JPanel();

       jp3 = new JPanel();

       //3.添加组件

       this.setLayout(new GridLayout(4,1,0,20));

       this.add(title);//第一行

       jp1.add(l1);

       jp1.add(jtf1);

       this.add(jp1);//第二行

       jp2.add(l2);

       jp2.add(jtf2);

       this.add(jp2);//第三行

       jp3.add(b1);

       jp3.add(b2);

       this.add(jp3);//第四行

       //4.设置

       this.pack();

       this.setLocationRelativeTo(null);

       this.setVisible(true);

      

       b1.addActionListener(this);//注册监听

       b2.addActionListener(this);//注册监听

    }

    public static void main(String[] args) {

       MyCopy mc = new MyCopy();

    }

    @Override

    public voidactionPerformed(ActionEvent e) {

       if(e.getSource()==b1){

           //拷贝

           String s1 = jtf1.getText();

           String s2 = jtf2.getText();

           try {

              //1.创建流

              FileInputStream fis = new FileInputStream(s1);//s1指定的地址上创建输入流

              FileOutputStream fos = new FileOutputStream(s2);//s3指定的地址上创建输出流

              //2.读写数据

              byte[] b = new byte[1024];

              int x = 0;

              while((x=fis.read(b))>0){

                  fos.write(b, 0, x);

              }

              JOptionPane.showMessageDialog(this, "拷贝成功!");

              //3.关闭流

              fos.close();

              fis.close();

           } catch (Exception e1) {

              // TODO Auto-generated catchblock

              e1.printStackTrace();

           }

       }else if(e.getSource()==b2){

           //取消

           jtf1.setText("");

           jtf2.setText("");

       }

    }

}

 

五、  System类对IO流的支持

 

static PrintStream

err “标准”错误输出流。   默认输出到屏幕

static InputStream

in “标准”输入流。        默认从键盘读取

static PrintStream

out “标准”输出流。       默认输出到屏幕

 

标准重定向:

      系统默认指定了输出和输入的往位置,但是我们可以通过如下方法来修改:

static void

setErr(PrintStream err) 重新分配“标准”错误输出流。

static void

setIn(InputStream in)  重新分配“标准”输入流。

static void

setOut(PrintStream out) 重新分配“标准”输出流。

 

案例一:

/**

 * setOut() 标准输出重定向

 */

package test_12_11;

import java.io.*;

public class Test5 {

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

           PrintStream ps = new PrintStream("D:\\abc\\2.txt");

           System.setOut(ps);//标准输出流重定向

           System.out.println("Hello World!");

           System.out.println("大家好!");

      }

}

 

案例二:

/**

 * setErr()标准错误输出流重定向

 */

package test_12_11;

import java.io.*;

import java.util.Date;

public class Test6 {

      PrintStream ps;

      FileOutputStream fis;

      public Test6(){

           try {

                 fis = new FileOutputStream("D:\\abc\\log.txt",true);

                 ps = new PrintStream(fis);

                 int i = 10/0;

           } catch (Exception e) {

                 System.setErr(ps);//标注错误输出流重定向

                 Date d = new Date();

                 System.err.println(d.toLocaleString()+"   "+e);

           }

      }

      public static void main(String[] args) {

           new Test6();

      }

}

 

 

案例三:标准键盘输入

package test_12_11;

import java.io.*;

public class Test7 {

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

           int a,b,sum;

           InputStreamReader isr = new InputStreamReader(System.in);//System.in是字节输入流将他转化成字符输入流 isr

           BufferedReader br = new BufferedReader(isr);

           System.out.println("请输入a的值:");

           a = Integer.parseInt(br.readLine());

           System.out.println("请输入b的值:");

           b = Integer.parseInt(br.readLine());

           sum = a+b;

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

      }

}

 

六、  对象流

对象流用来传输对象,要想实现对象的传输必须首先将对象实现序列化。

对象序列化的目的是将对象保存到磁盘中,或实现网络中直接传输对象,对象序列化机制允许将内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上,通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这种二进制流(无论是从磁盘获取还是从网络获取),都可以将这种二进制流恢复成原来的Java对象

如果要让某个对象支持序列化,必须让他的类是可序列化的,为了让某个类可序列化,该类必须实现如下两个接口中的一个:

Serializable(推荐)

Externalizable

Java中很多类已经实现类Serializable,该接口知识一个标记接口,实现该接口无需实现任何方法。

 

 

案例:

package test6_9;

import java.io.Serializable;

public class Dog implements Serializable{

    public String name;

    public String var;

    public String color;

    public int age;

    public Dog() {

    }

    public Dog(String name, String var,String color, int age) {

       this.name = name;

       this.var = var;

       this.color = color;

       this.age = age;

    }

    public void tell(){

       System.out.println("昵称:"+name+",品种:"+var+",颜色:"+color+",年龄:"+age);

    }

}

 

 

/**

 * 将对象写入到文件中

 */

package test6_9;

import java.io.*;

public class Test1 {

    Dog d = new Dog("大黄","牧羊犬","黄色",3);

    FileOutputStream fos;

    ObjectOutputStream oos;

    public Test1(){

       try {

           //1.创建对象

           fos = new FileOutputStream("G:\\abc\\dog.txt");

           oos = new ObjectOutputStream(fos);

           //2.写数据

           oos.writeObject(d);

           //3.关闭流

           oos.close();

           fos.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

      

    }

    public static void main(String[] args) {

       Test1 t = new Test1();

    }

}

 

/**

 * 从文件中读取对象

 */

package test6_9;

import java.io.*;

public class Test2 {

    Dog d;

    FileInputStream fis;

    ObjectInputStream ois;

    public Test2(){

       try {

           //1.创建流

           fis = new FileInputStream("G:\\abc\\dog.txt");

           ois = new ObjectInputStream(fis);

           //2.读取数据

           d = (Dog)ois.readObject();

           System.out.println(d.name);

           d.tell();

           //3.关闭流

           ois.close();

           fis.close();

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }

    public static void main(String[] args) {

       Test2 t = new Test2();

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值