🚩 Home / java / io.md

文件IO

java.io.File

构造方法:

  • File(String pathanme) 设置要操作的完整路径
  • File(File parent, String child) 设置父路径与子路径

文件基本方法:

  • createNewFile() 创建文件,存在文件返回false,否则返回true(即创建成功)
  • exists() 判断文件是否存在
  • delete() 删除文件

File类有一个常量 separator,用来定义不同操作系统下路径分隔符。

  • getParentFile() 获取父路径
  • mkdirs() 创建多级目录
  • mkdir() 创建单级目录

获取文件信息:

  • canRead() 可读

  • canWrite() 可写

  • length() 获取文件长度(字节长度)

  • lastModified() 上次修改时间

  • isFile() 是否是文件

  • isDirectory() 是否是目录

  • list() 返回当前目录下的文件列表

    class FileFilter implements FilenameFilter {

      private Pattern pattern;
    
      public FileFilter(String str) {
          this.pattern = Pattern.compile(str);
      }
      @Override
      public boolean accept(File dir, String name) {
          // TODO Auto-generated method stub
          return this.pattern.matcher(name).matches();
      }

    } public class MainTest {

      public static void main(String[] args) throws Exception{
          File file = new File("C:\\Users\\15391\\Desktop\\linux");
          String[] list = file.list(new FileFilter(".+\\.ppt"));
          for (String s : list) {
              System.out.println(s);
          }
      }

    }

java.io

  • 字节处理流:OutputStream(输出字节流)、InputStream(输入字节流)
  • 字符处理流:Writer(输出字符流)、Reader(输入字符流)

处理步骤:

  1. 通过字节流或字符流的子类为父类对象实例化
  2. 利用字节流或字符流中的方法实现数据的输入或输出
  3. 关闭资源

字节输出流:

  • abstract void write(int b) 写一个字节
  • void write(byte[] b) 写一个字节数字
  • void write(byte[] b, int off, int len) 写一段字节数组

子类:FileOutputStream:

  • FileOutputStream(File file)

  • FileOutputStream(File file, boolean append) 是否追加

    public class MainTest {

      public static void main(String[] args) throws Exception{
          String path = new File("").getAbsolutePath();
          path += File.separator + "test";
          File dir = new File(path);
          if (!dir.exists()) {
              dir.mkdirs();
          }
          path += File.separator + "test.txt";
    
          File file = new File(path);
          OutputStream os = new FileOutputStream(file);
          String hString = "hello world\n";
          os.write(hString.getBytes()); // 不存在文件会自动创建
          os.close();
      }

    }

InputStream

  • abstract int read() 读单个字节,读到底返回-1
  • int read(byte[] b) 读一组字节,返回是读取字节数,到底返回-1
  • read(byte[] b, int off, int len) 读一段长度字节

FileInputStream:

  • FileInputStream(File file)

    public class MainTest {

      public static void main(String[] args) throws Exception{
          String path = new File("").getAbsolutePath();
          path += File.separator + "test";
          File dir = new File(path);
          if (!dir.exists()) {
              dir.mkdirs();
          }
          path += File.separator + "test.txt";
    
          File file = new File(path);
          InputStream is = new FileInputStream(file);
          byte[] bs = new byte[1024];
          int len = is.read(bs);
          System.out.println("len:" + len + ", " + new String(bs, 0, len));
          is.close();
      }

    }

Writer & Reader

Writer:

  • void write(char[] cbuf) 输出字符数组
  • void write(String str) 输出字符串
  • append(CharSequence csq) 可追加

Reader:

  • int read(char[] cbuf) 读如一个流

字符字节流区别:

  • OutputStream不使用close()方法也能输出内容,但Writer就不能输出内容
  • 字符流不使用缓冲区,字节流使用缓冲区。字符流适用中文处理。Writer需要使用flush()进行强制刷新输出。

流转换

OutputStreamWriter: 继承自Writer

  • OutputStreamWriter(OutputStream out) 即将字节流作为参数输入,然后再向上转型变成字符流。

InputStreamReader: 继承自Reader

  • InputStreamReader(InputStream in)

字符编码

  • GBK/GB2312 国标,描述中文
  • ISO8859-1: 国家通用
  • UNICODE编码:十六进制方式存储,描述所有文章
  • UTF: 象形文字采用十六进制,普通字符采用ISO8859-1主要是utf-8

内存操作流

Java提供两类内存操作流:

  • 字节内存操作流:ByteArrayOutputStream, ByteArrayInputStream
  • 字符内存操作流:CharArrayWriter, CharArrayReader

ByteArrayInputStream:

  • public ByteArrayInputStream(byte buf[])

ByteArrayOutputStream:

  • public ByteArrayOutputStream();
  • 获取数据:public byte[] toByteArray()
  • 使用字符串形式来获取:public String toString();

管道流

两个线程通信。

PipedOutputStream,PipedInput Stream

  • public void connect(PipedInputStream snk)

PipedWriter, PipedReader

  • public void connect()

    class SendThread implements Runnable {

      private PipedOutputStream outputStream;
      public SendThread() {
          this.outputStream = new PipedOutputStream();
      }
    
      @Override
      public void run() {
          // TODO Auto-generated method stub
          for (int x = 0; x < 10; x++) {
              try {
                  this.outputStream.write(("[" + x + "]" + " hello").getBytes());
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
          try {
              this.outputStream.close();
          } catch (IOException e) {
              e.printStackTrace();
              // TODO: handle exception
          }
      }
      public PipedOutputStream getOutput() {
          return this.outputStream;
      }

    }

    class ReceiveThread implements Runnable {

      private PipedInputStream inputStream;
      public ReceiveThread() {
          this.inputStream = new PipedInputStream();
      }
    
      @Override
      public void run() {
          // TODO Auto-generated method stub

    // for (int x = 0; x < 10; x++) {

              byte[] data = new byte[1024];
              try {
                  int len = this.inputStream.read(data);
                  System.out.println(Thread.currentThread().getName() + " " + new String(data, 0 ,len));
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              try {
                  this.inputStream.close();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }

    // }

      }
      public PipedInputStream getInput() {
          return this.inputStream;
      }

    } public class MainTest {

      public static void main(String[] args) throws Exception{
          SendThread sendThread = new SendThread();
          ReceiveThread receiveThread = new ReceiveThread();
          sendThread.getOutput().connect(receiveThread.getInput());
          new Thread(sendThread, "消息发送").start();
          new Thread(receiveThread, "消息接收").start();
      }

    }

RandomAccessFile

对于大文件,当只访问文件的其中一个部分时使用RandomAccessFile。

  • public RandomAccessFile(File file, String mode);
    • 处理模式r、rw
  • public int skipBytes(int n) 向下跳
  • public void seek(long pos) 向回跳

可以由用户自行定义要读取的位置。

打印流

提高已有类的功能。

PrintStream

PrintWriter

System类

  • 标准输出 out
  • 标准错误 out
  • 标准输入 in

System.out和System.err并没有差别

可以修改输出流的流向。setOut()

键盘输入:

public class MainTest {
    public static void main(String[] args) throws Exception{
        InputStream iStream = System.in;
        byte[] data = new byte[1024];
        int len = iStream.read(data);
        System.out.println(new String(data, 0, len));
    }
}

BufferedReader

缓冲字符输入流

  • readLine()

实现键盘输入标准处理:

public class MainTest {
    public static void main(String[] args) throws Exception{
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        String mString = input.readLine();
        System.out.println(mString);
    }
}

Scanner

  • public Scanner(InputStream in) 构造

  • public boolean hasNext() 是否有数据

  • public String next() 取出数据

  • public Scanner useDelimiter(String pattern) 设置分隔符

    public class MainTest {

      public static void main(String[] args) throws Exception{
          Scanner scanner = new Scanner(System.in);
          if (scanner.hasNextInt()) {
              System.out.println(scanner.nextInt());
          }
      }

    }

结合正则:

public class MainTest {
    public static void main(String[] args) throws Exception{
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNext("\\d{4}-\\d{2}-\\d{2}")) {
            System.out.println(scanner.next());
        }
    }
}

输出使用打印流,输入使用Scanner。

对象序列换

java 序列化。

序列化:ObjectOutputStream, ObjectInputStream

  • public ObjectOutputStream(OutputStream out)

  • public ObjectInputStream(InputStream in)

  • writeObject()

  • readObject()

    @SuppressWarnings("serial") class Personn implements Serializable {

      private String name;
      private int age;
      public Personn(String name, int age) {
          this.setName(name);
          this.setAge(age);
      }
      public String getName() {
          return name;
      }
      public void setName(String name) {
          this.name = name;
      }
      public int getAge() {
          return age;
      }
      public void setAge(int age) {
          this.age = age;
      }

    } public class MainTest {

      public static void main(String[] args) throws Exception{
          saveObject(new Personn("xiaoqiang", 78));
          System.out.println(loadObject());
      }
      public static void saveObject(Object obj) throws Exception{
          ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:\\javaprogram\\JavaLearn\\test\\test.txt")));
          oos.writeObject(obj);
          oos.close();
      }
    
      public static Object loadObject() throws Exception{
          ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("D:\\javaprogram\\JavaLearn\\test\\test.txt")));
          Object obj = ois.readObject();
          ois.close();
          return obj;
      }

    }

transient关键字

序列化处理,默认对所有属性都序列化。但是加上transient关键字之后,该属性不被序列化。