IO流

常见的一些流

处理流,节点流
输入流,输出流
字节流,字符流
image.png

FileReader的两种读取方式

 fileReader = new FileReader(file);
            char[] buf = new char[1024];
            int len;
            //理解此处len以及read的形参的含义
            //方式一
//                while((( len=fileReader.read(buf))!=-1)) {
////                    for (int i = 0; i < len; i++) {
////                        System.out.print(buf[i]);
////
////                    }
////
////                }
            //方式二
            while ((len = fileReader.read(buf)) != -1) {
                String str = new String(buf, 0, len);
                System.out.println(str);
            }

用FileInputStream操作时,char[]换成byte[]

FileWriter的两种构造器

image.png

缓冲流(套在节点流外)

用缓冲流可提升读写效率,实现复制非文本文件例子,先上代码

@Test
    public void CopyByBuffer() {
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("3D王力宏 - 大城小爱.mp3")));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File("大城小爱.mp3")));
            byte[] buffer=new byte[20];
            int len;
            while((len=bufferedInputStream.read(buffer))!=-1){
                bufferedOutputStream.write(buffer,0,len);
            }
            System.out.println("复制成功");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bufferedInputStream!=null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bufferedOutputStream!=null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

缓冲流读写文本文件,提供一个新方法readLine(),但不会自动换行,需要在while循环中加.newLine()
image.png

转换流

image.png
实现字符集编码方式转换,上代码:

    @Test
           public void ConversionFlow() {
            InputStreamReader inputStreamReader = null;
            OutputStreamWriter outputStreamWriter = null;
            try {
                FileInputStream inputStream = new FileInputStream(new File("t1.txt"));
                FileOutputStream outputStream = new FileOutputStream(new File("t3.txt"));
                inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
                outputStreamWriter = new OutputStreamWriter(outputStream,"GBK");
                char[] buffer = new char[20];//此处要用字符集
                int len;
                while ((len = inputStreamReader.read(buffer)) != -1) {
                    outputStreamWriter.write(buffer, 0, len);
                }
                System.out.println("字符编码格式转换成功");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (inputStreamReader != null) {
                    try {
                        inputStreamReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (inputStreamReader != null) {
                    try {
                        outputStreamWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    }

可以在创建实例时加上字符集作为参数

序列化

一个自定义类要实现序列化:
首先要实现serializable接口
提供一个常量serialVersionUID
其包含所有属性都要实现serializable

RandomAccessFile:

创建改类对象时要指明模式,rw,r,rwd,rws
image.png
有seek方法,将指针调到固定角标位置。
使用例子:大文件的断点续传
代码示例:实现文件插入:

@Test
public void RandomAccessFileTest() {
    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile("t2.txt", "rw");
        byte[] buffer = new byte[1024];
        int len;
        StringBuilder stringBuilder = new StringBuilder((int) new File("t2.txt").length());
        raf.seek(2);
        while ((len = raf.read(buffer)) != -1) {
            stringBuilder.append(new String(buffer, 0, len));//注意此处写法
        }
        raf.seek(2);
        raf.write("xyz".getBytes());
        raf.write("吴佳豪".getBytes());
        raf.write(stringBuilder.toString().getBytes());//StringBuilder没有getbytes,可以现toString
        System.out.println("插入操作成功");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (raf != null) {
            try {
                raf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

StringBuilder无getbytes(),要先toString()

NIO(New IO/None-Blocking IO)jdk1.4添加

IO是基于流的
NIO是基于缓冲区的,基于通道的IO操作,更加高效

NIO2 jdk1.7添加

提供升级版的File类Path,通过Paths调用
image.png

网络编程

TCP测试:模拟客户端给服务器发送一句话,服务器接受打印并将此句话存储在本地,然后发消息给客户端表示接受成功,客户端接受并打印来自服务器的消息。代码如下:

因为read是个阻塞的方法,要注意必须用socket.shutdownOutput();主动关闭客户端的第一个输出流,才能进行后续操作

package IO;

import org.junit.Test;
import sun.management.BaseOperatingSystemImpl;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPTest2 {
    @Test
    public void Client() throws IOException {
        Socket socket = null;
        OutputStream os = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            InetAddress inet = InetAddress.getLocalHost();
            socket = new Socket(inet, 8888);
            os = socket.getOutputStream();
            os.write("我是客户端".getBytes());
            socket.shutdownOutput();//必须要加这句话,否则阻塞,C/S互相等待
            is = socket.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] buf = new byte[5];
            int len;
            while ((len = is.read(buf)) != -1) {
                baos.write(buf, 0, len);
            }
            System.out.println(baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                baos.close();
                os.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    public void Server() {
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            ss = new ServerSocket(8888);
            socket = ss.accept();
            is = socket.getInputStream();
            fos = new FileOutputStream(new File("TCPTest"));
            byte[] buf = new byte[10];
            int len;
            //使用byte[]如果有中文会出现乱码,可以改用如下方法
            //注意:此处ByteArray后面是OutputStream不是Input
            bos = new ByteArrayOutputStream();
            while ((len = is.read(buf)) != -1) {
                fos.write(buf, 0, len);
                bos.write(buf, 0, len);
            }
            System.out.println("接受语句存储本地成功");
            System.out.println(bos.toString());
            OutputStream os = socket.getOutputStream();
            os.write("已经成功收到客户端的信息".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
                bos.close();
                is.close();
                socket.close();
                ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


UDP编程测试

public class UDPTest {
    @Test
    public void sender() throws IOException {
        DatagramSocket socket=new DatagramSocket();
        byte[] buf ="我是UDP方式发送的消息".getBytes();
        DatagramPacket packet=new DatagramPacket(buf,0,buf.length,InetAddress.getLocalHost(),1234);
        socket.send(packet);
        socket.close();

    }
    @Test
    public void receiver() throws IOException {
        DatagramSocket socket=new DatagramSocket(1234);
        byte[] buf=new byte[1024];
        DatagramPacket packet=new DatagramPacket(buf,0,buf.length);
        socket.receive(packet);
        System.out.println(new String(packet.getData(),0,packet.getLength()));
    }
}

URL编程测试

image.png

Q.E.D.