Java IO流

文件传输基础——Java IO流》学习笔记

 

1.编码问题

public class EncodeDemo {
    public static void main(String[] args) throws Exception {
        String s = "慕课ABC";
        byte[] bytes1 = s.getBytes();//项目默认编码GBK
        for (byte b: bytes1) {
            // 把字节(转换成int)以16进制显示 &0xff:只留下后八位
            System.out.print(Integer.toHexString(b & 0xff) + " ");
        }
        System.out.println();
        
        byte[] bytes2 = s.getBytes("gbk");
        //c4 bd bf ce 41 42 43 
        //gbk 中文占2个字节 英文占1个字节
        for (byte b: bytes2) {
            System.out.print(Integer.toHexString(b & 0xff) + " ");
        }
        System.out.println();
        
        byte[] bytes3 = s.getBytes("utf-8");
        //e6 85 95 e8 af be 41 42 43 
        //utf-8 中文占3个字节 英文占1个字节
        for (byte b: bytes3) {
            System.out.print(Integer.toHexString(b & 0xff) + " ");
        }
        System.out.println();
        
        // Java是双字节编码utf-16be
        byte[] bytes4 = s.getBytes("utf-16be");
        //61 55 8b fe 0 41 0 42 0 43 
        //utf-16be中文占2个字节 英文占2个字节
        for (byte b: bytes4) {
            System.out.print(Integer.toHexString(b & 0xff) + " ");
        }
        System.out.println();
        
        /**
         * 当字节序列采用某种编码时 将字节序列转换成字符串 也需要使用相同编码
         */
        String str1 = new String(bytes4);
        System.out.println(str1);    // 乱码
        String str2 = new String(bytes4, "utf-16be");
        System.out.println(str2);    // 正常
    }
}
EncodeDemo.java

 

文本文件 就是字节序列 可以是任意编码的字节序列

如果在中文机器上直接创建文本文件,那么该文件只认识ANSI编码,但是粘贴过来的文件可以是任意格式。

Eclipse中一个只能识别项目默认的编码。

 

2.File类

Java.io.File类用于表示文件/目录

File只用于表示文件信息(名称、大小等),不能用于文件内容的访问。

package com.wenr.io;

import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) {
        // 构造函数
        File file = new File("E:\\javaio");
        if (!file.exists())
            file.mkdir();
        // 是否是一个目录
        System.out.println(file.isDirectory());
        // 是否是一个文件
        System.out.println(file.isFile());
        
        //File file2 = new File("E:\\javaio\\mdzz.txt");
        File file2 = new File("E:\\javaio", "mdzz.txt");
        
        if (!file2.exists()) {
            try {
                file2.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            file2.delete();
        }
        System.out.println(file);
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getName() + " " + file.getParent());
        System.out.println(file2.getName() + " " + file2.getParent());
    }
}
FileDemo

 

import java.io.File;
import java.io.IOException;

public class FileUtils {
    // 列出指定目录下(包括子目录)所有文件
    public static void listDirectory(File dir) throws IOException {
        if (!dir.exists()) {
            throw new IllegalArgumentException("目录:" + dir + "不存在.");
        }
        if (!dir.isDirectory()) {
            throw new IllegalArgumentException(dir+"不是目录.");
        }
        //String[] filenames = dir.list(); // 返回子目录名称的字符处数组
        File[] files = dir.listFiles();
        for (File file: files) {
            if (file.isDirectory()) {
                FileUtils.listDirectory(file);
            } else {
                System.out.println(file);
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
        FileUtils.listDirectory(new File("E:\\java"));
    }

}
FileUtils

 

3.RandomAccessFile

Java提供的对文件内容的访问类,读写文件。可以随机访问文件。

 

Java文件模型,在硬盘上是Byte存储,是数据的集合。

打开文件,有两种模式"rw"(读写),"r"(只读)

写方法,raf.write(int)-->只写一个字节(后八位)

读方法, int b=raf.read()-->读一个字节

读完文件一定要关闭。

package com.wenr.io;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;

public class RafDemo {

    public static void main(String[] args) throws IOException {
        File demo = new File("demo");
        if (!demo.exists()) {
            demo.mkdir();
        }
        File file = new File(demo, "raf.dat");
        if (!file.exists()) {
            file.createNewFile();
        }
        
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        System.out.println(raf.getFilePointer());
        
        raf.write('A'); 
        System.out.println(raf.getFilePointer());
        raf.write('B');
        System.out.println(raf.getFilePointer());
        
        int i = 0x7fffffff;
        // 用write方法每次只能写一个字节,如果要把i写进去就得写4次
        raf.write(i >>> 24);//高8位
        raf.write(i >>> 16);
        raf.write(i >>> 8);
        raf.write(i);
        System.out.println(raf.getFilePointer());
        
        //可以直接写一个int
        raf.writeInt(i);
        System.out.println(raf.getFilePointer());
        
        String s = "中";
        byte[] gbk = s.getBytes();
        raf.write(gbk);
        System.out.println(raf.length());
        
        // 读文件  必须把指针移到头部
        raf.seek(0);
        // 一次性读取  把文件中的内容都读到字节数组中
        byte[] buf = new byte[(int)raf.length()];
        raf.read(buf);
        System.out.println(Arrays.toString(buf));
        
        for (byte b: buf) {
            System.out.print(Integer.toHexString(b & 0xff) + " ");
        }
        
        raf.close();
    }

}
RafDemo.java

 

 

4.字节流(char流)InputStream/OutputStream

1)字节流

InputStream(抽象类)抽象了应用程序读取数据方式

OutputStream(抽象类)抽象了应用程序写数据方式

2)EOF= End 读到-1就读到结束

3)输入流基本方法

  int b = in.read();//读取一个字节填充到int第八位 -1是EOF

  in.read(byte[] buf)

  in.read(byte p[] buf, int start, int size);

4)输出流基本方式

  out.write(int b) 写一个byte到流

  out.write(byte[] buf) 将buf字节数组写入到流

  out.write(byte[] buf, int start, int size);

5)FileInputStream--->具体实现了在文件上读取数据

 

 

 

图片来源

 

package com.wenr.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;


public class TestIOStream {
    
    public static void testFileInputStream() throws IOException {
        // 文件输入流
        InputStream in = new FileInputStream("demo/test.txt");
        int x;
        // 读取文件demo/test.txt 读一个字节输出一个字节
        while ((x = in.read()) != -1) {
            System.out.print(x + " ");
        }
        System.out.println();
        
        in = new FileInputStream(new File("demo/test.txt"));
        byte[] b = new byte[20];
        int off = 3;
        int len = 10;
        // 读取文件内容到数字b,从b[off]位置写入,最多读len长度的字节
        // in.read(byte[] b) 相当于 read(b, 0, b.length)
        while ((x = in.read(b, off, len)) != -1) {
            for (byte bb: b)
                System.out.print(bb + " ");
            System.out.println();
        }
        in.close();
    }
    
    
    public static void testFileOutputStream() throws IOException {
        OutputStream out = new FileOutputStream("demo/test.txt");
        int i = 0x01020304;
        // 只能写一字节到文件 蓝儿int有4字节 所以只输入了低8位 也就是04
        out.write(i);
        byte[] b = {(byte)0xA,(byte)0xB, (byte)0xC, (byte)0xD, (byte)0xE, (byte)0xF};
        // 把字节数组写入文件
        out.write(b);
        // 向文件写入b[off] b[off+1] ... b[off+len-1]
        int off = 1, len = 2;
        out.write(b, off, len);
        out.close();
    }
    
    static class People implements Serializable {
        String name;
        int age;
        People() {}
        People(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String toString() {
            return "name:" + name + ",age:" + age;
        }
    }
    
    public static void testObjectStream() throws FileNotFoundException, IOException, ClassNotFoundException {
        // 文件输出流    构造函数的参数是OutputStream 把对象序列化写入文件
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("demo/test.txt"));
        People p1 = new People("张三", 21);
        People p2 = new People("李四", 22);
        oos.writeObject(p1);
        oos.writeObject(p2);
        oos.close();
        // 对象输入流  构造函数的参数是InputStream
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("demo/test.txt"));
        People p = (People)ois.readObject();
        System.out.println(p);
        p = (People)ois.readObject();
        System.out.println(p);
        ois.close();
    }
    
    public static void testBufferedStream() throws IOException {
        // 通过设置缓存区提高存取效率
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("demo/test.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("demo/test1.txt"));
        int i;
        while ((i = bis.read()) != -1) {
            bos.write(i);
        }
        bos.flush();
        bis.close();
        bos.close();
    }
    
    public static void testDataStream() throws IOException {
        // 设置模式——>装饰模式
        // 按格式读取
        String file = "demo/dos.dat";
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
        dos.writeInt(10);
        dos.writeLong(-10L);
        dos.writeDouble(10.5);
        // 采用utf-8编码
        dos.writeUTF("张三");
        dos.close();
        
        DataInputStream dis = new DataInputStream(new FileInputStream(file));
        int i = dis.readInt();
        long l = dis.readLong();
        double d = dis.readDouble();
        System.out.println(i + "," + l + "," + d);
        String s = dis.readUTF();
        System.out.println(s);
        dis.close();
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //testFileOutputStream();
        //testFileInputStream();
        //testObjectStream();
        //testBufferedStream();
        testDataStream();
    }
}
TestIOStream.java

 

5.字符流

字符流处理的一般是文本文件

1、字符流的基本实现

 InputStreamReader 完成byte流解析为char流,按照编码解析

 OutputStreamWriter 提供char流到byte流。

2、

FileWriter/FileWriter : 和InputStreamReader/OutputStreamWriter功能差不多,但是字符编码等设置是默认的。

3、字符流的过滤器

BufferedReader/BufferedWriter

package com.wenr.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class TestCharSteam {

    public static void testInputStreamReader() throws IOException {
        InputStream in = new FileInputStream("demo/test.txt");
        InputStreamReader isr = new InputStreamReader(in, "utf-8");// 默认项目编码

        FileOutputStream out = new FileOutputStream("demo/test1.txt");
        OutputStreamWriter osw = new OutputStreamWriter(out);

        int c;
        // 每次读取一个字符
        // c = isr.read()
        char[] buffer = new char[20];
        int count = 0;
        int a = 0;
        // 每次读取buffer.length个字符
        while ((c = isr.read(buffer)) != -1) {
            String s = new String(buffer, 0, c);
            System.out.print(s);
            osw.write(buffer, 0, c);
        }
        osw.close();
    }

    public static void testBuffered() throws IOException {
        // 构造参数 Reader
        BufferedReader br = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream("demo/test.txt"), "utf-8"));
//        BufferedWriter bw = new BufferedWriter(
//                new OutputStreamWriter(
//                        new FileOutputStream("demo/test1.txt")));
        PrintWriter pw = new PrintWriter("demo/test1.txt");
        String line;
        while ((line = br.readLine()) != null) {
            // 读取一行不会读取换行!
            System.out.println(line);
            pw.println(line);
            pw.flush();
//            bw.write(line);
//            bw.newLine();
        }
        br.close();
        //bw.close();
        pw.close();
    }

    public static void testFileWriterAndReader() throws IOException {
        // 不能设置编码 所以比编码不同的时候还是需要InputStreamReader&OutputStreamWriter
        FileReader fr = new FileReader("demo/test.txt");
        FileWriter fw = new FileWriter("demo/test1.txt");
        // FileWriter(fileName, true); true 表追加append
        char[] buffer = new char[2056];
        int c;
        while ((c = fr.read(buffer)) != -1) {
            fw.write(buffer);
        }
        fr.close();
        fw.close();
    }

    public static void main(String[] args) throws IOException {
        // testInputStreamReader();
        // testFileWriterAndReader();
        testBuffered();
    }

}
TestCharSteam.java

 

posted @ 2016-11-21 22:27  我不吃饼干呀  阅读(206)  评论(0编辑  收藏  举报