Java IO

Posted by whaler404 on January 25, 2024

输入输出处理

IO流的概念和划分

  • 数据流stream:有顺序、有起点、有终点的字节集合;Java通过流来输入和输出,连接物理设备

  • Java流的划分:字节流和字符流,读写单位不同,都用Read(),Write()方法

    字节流输入类

    image-20231218114316481

    字节流输出类

    image-20231218114414221

    字符流输入类

    image-20231218114509448

    字符流输出类

    image-20231218114526200

文件的操作

  • File类:对文件的引用和表示,通过File类获得文件、目录的描述信息

  • File对象构造

    File f1 = new File("D:/Java");
    File f2 = new File("D:/Java","test.txt");
    File f3 = new File(f1,"test.txt");
    File f4 = new File("file://D:/Java/test.txt");
    
  • File类的方法

    boolean canRead()//测试文件是否可读
    boolean delete()//删除文件
    File getAbsoluteFile()//返回绝对文件名
    boolean isDirectory()//是否是目录
    long lastModified()//上次修改时间,从1970年1月1号开始的标准时间(UTC)的毫秒数
    
    import java.io.*;
      
    public class FileOperationsExample {
      
        public static void main(String[] args) {
            createFile();
            writeToFile();
            readFromFile();
            copyFile();
            deleteFile();
        }
      
        private static void createFile() {
            File file = new File("example.txt");
      
            try {
                if (file.createNewFile()) {
                    System.out.println("File created successfully.");
                } else {
                    System.out.println("File already exists.");
                }
            } catch (IOException e) {
                System.out.println("An error occurred while creating the file.");
                e.printStackTrace();
            }
        }
      
        private static void writeToFile() {
            try (FileWriter writer = new FileWriter("example.txt")) {
                writer.write("Hello, this is a sample text.");
                System.out.println("Data written to the file.");
            } catch (IOException e) {
                System.out.println("An error occurred while writing to the file.");
                e.printStackTrace();
            }
        }
      
        private static void readFromFile() {
            try (FileReader reader = new FileReader("example.txt")) {
                int character;
                while ((character = reader.read()) != -1) {
                    System.out.print((char) character);
                }
            } catch (IOException e) {
                System.out.println("An error occurred while reading the file.");
                e.printStackTrace();
            }
            System.out.println(); // Print a newline for better output
        }
      
        private static void copyFile() {
            File sourceFile = new File("example.txt");
            File destinationFile = new File("copy.txt");
      
            try (FileInputStream inputStream = new FileInputStream(sourceFile);
                 FileOutputStream outputStream = new FileOutputStream(destinationFile)) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
                System.out.println("File copied successfully.");
            } catch (IOException e) {
                System.out.println("An error occurred while copying the file.");
                e.printStackTrace();
            }
        }
      
        private static void deleteFile() {
            File file = new File("example.txt");
      
            if (file.delete()) {
                System.out.println("File deleted successfully.");
            } else {
                System.out.println("Failed to delete the file.");
            }
        }
    }
    

字节Byte流处理

  • InputStream/OutputStream:

    int read( )
    int read(byte b[ ])
    int read(byte b[ ], int offset, int len)
      
    void close( )
    void flush( )
    void write(int b)
    void write(byte b[ ])
    void write(byte b[ ], int offset, int len)
    
  • 标准输入/输出流:通过System类实现,定义三个流变量in、out、err

    • System.in作为字节输入流类InputStream的对象实现标准输入。通过read()方法从键盘接受数据。
    • System.out作为打印流类PrintStream的对象实现标准输出。对PrintStream类进行了扩充,支持数据的格式化输出,增加了printf()方法。
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
      
    public class StandardInputStreamOutputStreamExample {
        public static void main(String[] args) {
            // 使用System.in获取标准输入流
            InputStream inputStream = System.in;
      
            // 使用System.out获取标准输出流
            OutputStream outputStream = System.out;
      
            try {
                // 从标准输入流读取字节数据
                System.out.print("Enter something: ");
                int data = inputStream.read();
      
                // 处理读取的数据
                System.out.println("You entered: " + (char) data);
      
                // 将数据写入到标准输出流
                String message = "Hello, StandardOutputStream!";
                byte[] messageBytes = message.getBytes();
                outputStream.write(messageBytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
      
      
    //static PrintStream err 
    //static InputStream in  
    //static PrintStream out 
    
    //JDK5.0新功能
    import java.util.Scanner;
    public class TestScanner {
    	public static void main(String[] args) {
    		Scanner cin = new Scanner(System.in);
    		int a = cin.nextInt(), b = cin.nextInt();
    		System.out.println(a + b);
    	}
    }	
    
  • 文件字节流:inputstream/outputstream都是抽象类,不能实例化,都是使用其子类

    FileInputStream和FileOutputStream数据源和接收器都是文件

    • 构造方法

      FileInputStream f1 = new FileInputStream(Test.java);
      File f = new File("Test.java");
      FileInputStream f2 = new FileInputStream(f);
      //能引发FileNotFoundException异常
          
      FileOutputStream(String filePath)
      FileOutputStream(File fileObj)
      FileOutputStream(String filePath, boolean append)
      FileOutputStream(File fileObj, boolean append)
      //文件输出流创建不依赖于文件是否存在
      
    • 方法

      import java.io.FileInputStream;
      import java.io.IOException;
          
      public class FileInputStreamExample {
          public static void main(String[] args) {
              String filePath = "path/to/your/file.txt";
          
              try (FileInputStream fileInputStream = new FileInputStream(filePath)) {
                  int data;
                  // 输入流结束则返回-1
                  while ((data = fileInputStream.read()) != -1) {
                      // 处理读取的数据,这里简单地打印到控制台
                      System.out.print((char) data);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
          
      
      import java.io.FileOutputStream;
      import java.io.IOException;
          
      public class FileOutputStreamExample {
          public static void main(String[] args) {
              String filePath = "path/to/your/output.txt";
          
              try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
                  String data = "Hello, FileOutputStream!";
                  fileOutputStream.write(data.getBytes());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
          
      //public void write(int b) throws IOException
      //b是int类型时,占用4个字节,只有最低的一个字节被写入输出流,忽略其余字节。
      
  • 过滤流:在读写数据时对数据处理,提供了同步机制,线程互斥访问流对象

    过滤对象:文件输入输出流

    BufferedInputStream(InputStream input)
    BufferedInputStream(InputStream input, int bufSize)
    BufferedOutputStream(OutputStream output)
    BufferedOutputStream(OutputStream output, int bufSize)
    
  • 随机存取流:RandomAccessFile类提供了随机访问文件模式,可同时读写、任意位置读写

字符流Char处理

  • Reader/Writer:字符流操作的抽象类。它们分别用于读取和写入字符数据

    • Reader:定义字符流输入模式下的抽象类,IOException异常,int read()
    • Writer:输出模式下的抽象类,返回void,void write(int ch)
  • 文件字符流类

    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
      
    public class ReaderWriterExample {
        public static void main(String[] args) {
            String inputFilePath = "path/to/your/input.txt";
            String outputFilePath = "path/to/your/output.txt";
      
            // 使用FileReader读取文件
            try (FileReader fileReader = new FileReader(inputFilePath);
                 FileWriter fileWriter = new FileWriter(outputFilePath)) {
      
                int data;
                while ((data = fileReader.read()) != -1) {
                    // 处理读取的字符数据
                    System.out.print((char) data);
      
                    // 使用FileWriter写入文件
                    fileWriter.write(data);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
      
    

    使用适合大文件的效率更高的Buffer字符流

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
      
    public class BufferedReaderWriterExample {
        public static void main(String[] args) {
            String inputFilePath = "path/to/your/input.txt";
            String outputFilePath = "path/to/your/output.txt";
      
            // 使用BufferedReader读取文件
            try (BufferedReader bufferedReader = new BufferedReader(new FileReader(inputFilePath));
                 BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(outputFilePath))) {
      
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    // 处理读取的一行数据
                    System.out.println("Read line: " + line);
      
                    // 使用BufferedWriter写入文件
                    bufferedWriter.write(line);
                    bufferedWriter.newLine(); // 写入换行符
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
      
    

字节流和字符流的转化

  • 字节流和字符流的读写单位不同,特别是在不同编码情况下

  • InputStreamReader和OutputStreamWriter作为字符和字节的中介,字节流转化为字符流

  • 可以指定编码规范

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
      
    public class StandardInputOutputExample {
        public static void main(String[] args) {
            // 使用BufferedReader读取标准输入流
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
                System.out.print("Enter something: ");
                String userInput = reader.readLine();
                System.out.println("You entered: " + userInput);
            } catch (IOException e) {
                e.printStackTrace();
            }
      
            // 使用PrintWriter写入标准输出流
            try (PrintWriter writer = new PrintWriter(System.out, true)) {
                writer.println("This message will be printed to standard output.");
            }
        }
    }
    
    File file = new File("src/StreamToReaderWriter.java");
    FileInputStream fin = new FileInputStream(file);
    InputStreamReader isr = new InputStreamReader(fin, "GBK");
      
    FileOutputStream fout = new FileOutputStream("copy-of-file.txt");
    OutputStreamWriter osw = new OutputStreamWriter(fout, "GBK");
    

串行化

  • 串行化的概念

    • 持续化persistence:对象记录自己的状态以便再生
    • 串行化serialization:对象通过写出描述自己状态的数值来记录自己的过程 串行化的主要任务:写出对象实例变量的数值
  • 串行化的方法

    • 实现了Serializable接口的对象才可以被串行化,该接口没有定义任何成员,仅用来标记一个类可以被串行化。串行化可以被继承。

      import java.io.*;
          
      class Student implements Serializable {
          private static final long serialVersionUID = 1L;
          
          private String name;
          private int age;
          
          public Student(String name, int age) {
              this.name = name;
              this.age = age;
          }
          
          @Override
          public String toString() {
              return "Student{name='" + name + "', age=" + age + '}';
          }
      }
          
      public class SerializationExample {
          public static void main(String[] args) {
              // 创建一个Student对象
              Student student = new Student("John", 20);
          
              // 串行化对象
              serializeObject(student, "serialized_student.ser");
          
              // 反串行化对象
              Student deserializedStudent = (Student) deserializeObject("serialized_student.ser");
              System.out.println("Deserialized Student: " + deserializedStudent);
          }
          
          // 串行化对象到文件
          private static void serializeObject(Object obj, String filePath) {
              try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) {
                  oos.writeObject(obj);
                  System.out.println("Object serialized to " + filePath);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          
          // 反串行化对象
          private static Object deserializeObject(String filePath) {
              try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) {
                  Object obj = ois.readObject();
                  System.out.println("Object deserialized from " + filePath);
                  return obj;
              } catch (IOException | ClassNotFoundException e) {
                  e.printStackTrace();
                  return null;
              }
          }
      }
      
      ObjectOutputStream (OutputStream out);
      FileOutputStream fout = new FileOutputStream("data1.ser");
      ObjectOutputStream oout = new ObjectOutputStream(fout);
          
      ObjectInputStream(InputStream in);
      FileInputStream fin = new FileInputStream("data1.ser");
      ObjectInputStream oin = new ObjectInputStream(fin);
      

      相关资料

  • Spring Boot 分片上传、断点续传、大文件上传、秒传,应有尽有,建议收藏!!
  • java guide IO