简单入门JAVAIO

java IO 输入输出流
编码问题
File 类的使用
RandomAccessFile的使用
字节流的使用
字符流的使用
对象的序列化和反序列化

1.编码问题
GBK编码,中文占用两个字节,英文占用一个字节。
UTF-8编码,中文占用三个字节,英文占用一个字节。
java是双字节编码,UTF-16be,中文占用两个字节,英文也是占用两个字节。
tips:当你的字节序列是某种编码时,这个时候想把字节序列变成字符串,也需要这个编码,不然会出现乱码。 文本文件就是字节序列,可以是任意编码的字节序列,如果我们在中文机器上面自动创建文本文件,那么该文件只认识ansi编码,
相关代码:

public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "王文杰123";
        byte[] bytes1 = s.getBytes(); // 转换成字节序列使用的是项目默认的字节编码
        byte[] bytes = s.getBytes("GBK"); // 转换成字节序列使用的是项目默认的字节编码
//        for (byte b : bytes) {
//            //把字节转换成了int,然后以16进制显示
//            System.out.print(Integer.toHexString(b & 0xff)+"  ");
//        }
        byte[] bytes2 = s.getBytes("UTF-16BE"); // 转换成字节序列使用的是项目默认的字节编码
        for (byte b : bytes2) {
            //把字节转换成了int,然后以16进制显示
            System.out.print(Integer.toHexString(b & 0xff)+"  ");
        }
        System.out.println(new String(bytes2,"UTF-16BE"));
        System.out.println(new String(bytes2,"GBK"));
    }

2.FILE 类的使用
常用的API
java.IO.file类用于表示目录和文件
file类只用于表示文件或者目录的信息,比如名称,大小,etc. 。不能用于文件内容的访问。

相关代码:
{
    public static void main(String[] args) throws IOException {
        File file = new File("D:" + File.separator + "IDEA/wenjiewang");
        System.out.println("判断文件是否存在:" + file.exists());
        if (!file.exists()) {
            file.mkdir();
        } else {
            file.delete();  // 删除文件或者目录
        }
        // 不是目录或者目录不存在返回false
        System.out.println("判断是否是目录:" + file.isDirectory());
        System.out.println("判断是否是文件:" + file.isFile());
        file.createNewFile(); //创建文件
        // 常用的File对象的API
        System.out.println(file); // 打印file对象的path
        System.out.println(file.getAbsolutePath()); // file 对象的目录
        System.out.println(file.getName()); // 打印文件的名称
        System.out.println(file.getParent()); // 获取父目录
    }
}

常用操作
获取目录下的子文件

	// File 类的常用操作
	// 过滤 遍历
	public class FileUtils {
  	 	 public static void main(String[] args) {
      	  listDirectory(new File("D:\\IDEA\\mmall\\src\\main\\java\\com\\mmall\\common"));
	    }
    //  列出指定目录以及子目录下的所有文件
    public static void listDirectory(File dir) {
        if (!dir.exists() || !dir.isDirectory()) {
            throw new IllegalArgumentException("目录" + dir + "不存在或不是目录!");
        }
        // 获取子目录  返回字符串
        String[] dirList = dir.list();
        for (String path : dirList) {
            System.out.println(path);
        }
        // 获取子目录  返回File对象
        File[] fileList = dir.listFiles();
        for (File file : fileList) {
            System.out.println(file);
            // 递归遍历整个目录
            if (file.isDirectory()) {
                listDirectory(file);
            }

        }
        // 遍历整个目录 然后返回.java结尾的所有文件目录
        File[] list = dir.listFiles(new FilenameFilter() {
            private Pattern pattern = Pattern.compile(".java");

            @Override
            public boolean accept(File dir, String name) {
                return pattern.matcher(name).matches();
            }
        });
        Arrays.sort(list);
        for (File path : list) {
            if (path.isDirectory()) {
                listDirectory(path);
            }
            System.out.println(path);
        }
    }
}

3.RandomAccessFile的使用
java提供的对文件内容的访问,既可以读文件,也可以写文件,而且,可以随机访问文件,可以访问文件的任意位置。
java 文件模型
1.1. 在硬盘上的文件是byte数组的集合,
打开文件
2.1 有两种模式"RW",“R”, 读写和只读的两种模式
RandomAccessFile raf= new RandomAccessFile(file , “RW”);

文件指针Pointer默认为0,随着你的操作,文件的指针会后移,数字变大
写方法
3.1 raf.write(int); ----> 只写一个字节。同时指针指向下个位置,准备下次写;
读方法
4.1 int b= raf.read() —> 读一个字节,然后把字节转化为整数
文件读写完以后一定要关闭

相关代码
{
    public static void main(String[] args) throws IOException {
        File file = new File(".//wenjie//raf.txt");
        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');
        int i = 0x7fffffff;
        // 用write方法每次只能写一个字节,如果把i写进去就得写四次。
        raf.write(i >>> 24);
        raf.write(i >>> 16);
        raf.write(i >>> 8);
        raf.write(i);
        System.out.println("指针的位置:" + raf.getFilePointer());
        raf.writeInt(i);
        // 读文件,必须把指针移到最前面;
        raf.seek(0);
        // 一次性读取,把所有文件都读取到字节数组中
        byte[] buf = new byte[(int) raf.length()];
        raf.read(buf);
        for (byte b : buf) {
            System.out.print(Integer.toHexString(b & 0xff)+"   ");
        }
        System.out.println(Arrays.toString(buf));

        // 构造成字符串
        String s = new String(buf);
        System.out.println(s);
        // 操作完要关闭。
        raf.close();
    }
}


IO流可以分为输入流,输出流。输入输出流又可以分为字节流,字符流。**
1.字节流
1.1 InputStream、OutputStream
InputStream 抽象了应用程序读取数据的方式;
OutputStream 抽象了应用程序写出数据的方式。
1.2 EOF = END 读到-1表示读到结尾
1.3 输入流的基本方法
int a = input.read();读取一个字节,无符号填充到int低八位,-1 是EOF。
in.read(byte[] bufs); 读取数据填充到字节数组bufs;
in.read(byte[] bufs,int start,int size); 读取数据到buf,从start开始读取size个长度。
1.4 输出流
out.write(int a); 写出一个byte到流,a的低八位。
out.write(byte[] bufs); 将buf字节数组写入到流。
out.write(byte[] bufs,int start,int size); 同read相同,写bufs到流从start开始写size。

4 字节流的使用
文件输入流FileInputStream
FilInputStream 具体实现了从文件上读取数据。
相关代码

{
    // 读取文件内容,然后以16进制输出到控制台
    // 每输出十个,然后换行
    public static void inputStreamRead(String path) throws IOException {
        FileInputStream fis = null;
        try {
            File file = new File(path);
            //把文件作为流去操作;
            fis = new FileInputStream(file);
            int b;
            int i = 1;
            while ((b = fis.read()) != -1) {
                if (b <= 0xf) {
                    //单位数前面补0
                    System.out.print("0");
                }
                System.out.printf(Integer.toHexString(b));
                System.out.print("  ");
                i++;
                if (i % 15 == 0) {
                    System.out.println();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fis.close();
        }
    }

    public static void inputStreamByte(String path) throws IOException {
        FileInputStream fis = null;
        byte[] buf = new byte[20 * 1024];
        try {
            File file = new File(path);
            //把文件作为流去操作;
            fis = new FileInputStream(file);
            // 从0开始读,读出来的数据放到buf数组中,返回的是读取的字节的个数
            // 一次性读完说明数组足够大
            int b = fis.read(buf, 0, buf.length);
            int j = 0;
            for (int i = 0; i < b; i++) {
                System.out.print(Integer.toHexString(buf[i] & 0xFF) + "  ");
                if (j++ % 15 == 0) {
                    System.out.println();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fis.close();
        }
    }

    public static void inputStreamByte2(String path) throws IOException {
        FileInputStream fis = null;
        byte[] buf = new byte[20 * 1024];
        try {
            File file = new File(path);
            fis = new FileInputStream(file);
            int j = 0;
            int b = 0;
            while ((b = fis.read(buf, 0, buf.length)) != -1) {
                for (int i = 0; i < b; i++) {
                    System.out.print(Integer.toHexString(buf[i] & 0xFF) + "  ");
                    if (j++ % 15 == 0) {
                        System.out.println();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fis.close();
        }
    }
}

buf[i] & 0xFF
char 是8位,int是32位,char转到int的时候前面会自动补1,所以需要使用0xFF将前面的24位数字清空。
文件输入流FileInputStream
实现了向文件中写出byte数据的方法

{
    public static void main(String[] args) throws IOException {
        File file = new File("./wenjie/raf1.txt");
        FileOutputStream fos = null;
        try {
            // 如果文件不存在就会自动创建,存在就会删除后创建
            // 第二个参数就会控制在后面追加内容,不会删除。
            fos = new FileOutputStream(file);
            String a = "这是一个测试用的字符串!";
            byte[] bytes = a.getBytes();
            fos.write(bytes);
            int i = 11;
            fos.write(i >>> 24);
            fos.write(i >>> 16);
            fos.write(i >>> 8);
            fos.write(i);
            fos.write(String.valueOf(i).getBytes());
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fos.close();
        }
    }
}

DataoutputStream / DataInputStream
是对流的扩展,可以更加方便的读取int long 字符等类型的数据
DataOutputStream —>

public static void main(String[] args) throws IOException {
    FileOutputStream fos = null;
    DataOutputStream dos = null;
    FileInputStream fis = null;
    DataInputStream dis = null;
    try {
        File file = new File("./wenjie/raf.txt");
        fos = new FileOutputStream(file);
        dos = new DataOutputStream(fos);
        fis = new FileInputStream(file);
        dis = new DataInputStream(fis);
        int a = 10;
        dos.writeInt(a);
        dos.writeUTF("学习!");
        // 输出10,使用readInt可以读取写入的数据
        System.out.println(dis.readInt());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        fos.close();
        dos.close();
    }
}

字节缓冲流
BufferedInputStream BufferedOutputStream
这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或者读取操作时,都会加上缓冲,这种流模式提高了io的性能。更加方便的进行写入读取操作。写入到缓冲区,再进行写入,提高了性能。

{
    /**
     * 使用带缓冲的字节流进行复制操作。
     */
    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("./wenjie/raf.txt")));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("./wenjie/raf1.txt")));
        int buf;
        while ((buf = bis.read()) != -1){
            bos.write(buf);
            // 刷新缓冲区
            bos.flush();
        }
        bis.close();
        bos.close();
    }
}


猜你喜欢

转载自blog.csdn.net/sinat_16744909/article/details/90143219