Java打怪之路----Java高级之IO流与网络编程

(一)File类

file类主要就是用来读取文件的,File类提供一些方法,例如读取文件的名称,获取文件的路径等
File类的使用如下:

import org.junit.Test;

import java.io.File;

public class TestFileClass {
    
    
    @Test
    public void testFile(){
    
    
        File file=new File("IO","data.txt");
        System.out.println(file.getAbsoluteFile());
        File dir1 = new File("D:/IOTest/dir1");
        if (!dir1.exists()) {
    
     // 如果D:/IOTest/dir1不存在,就创建为目录
            dir1.mkdir();
        }
// 创建以dir1为父目录,名为"dir2"的File对象
        File dir2 = new File(dir1, "dir2");
        if (!dir2.exists()) {
    
     // 如果还不存在,就创建为目录
            dir2.mkdirs();
        }
        File dir4 = new File(dir1, "dir3/dir4");
        if (!dir4.exists()) {
    
    
            dir4.mkdirs();
        }
    }
}

(二)IO流

对于文本文件(.txt,.java,.c)使用字符流处理
对于非文本文件(.jpg,.mp3,.avi)使用字节流处理

2.1IO流的分类

在这里插入图片描述
在这里插入图片描述

处理流套在节点流外面,一般释放资源时只需要释放处理流,节点流自动释放。

2.2InputStreamReader&&outputStreamWriter(字符流 节点流)

以字符流Reader为例,读取一个文件中的信息

//read()方法
    @Test
    public void testReader(){
    
    
        FileReader fr = null;

        try {
    
    
            //File实例化
            File file = new File("data.txt");
            //FileReader实例化
            fr = new FileReader(file);
            //read读取出来的是整数  如果读到最后  返回-1
            int a = fr.read();
            while (a != -1) {
    
    
                System.out.println(a);
                a = fr.read();
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        finally {
    
    
            try {
    
    
                fr.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
    }
  //read() 使用read的重载方法

这里注意,直接在方法上抛异常会导致垃圾可能不能释放。使用try catch保证finally最后的语句会执行。 (快捷键alt+shift+T)
步骤和上面一样

    @Test
    public void Writer(){
    
    
        FileWriter fr = null;
        try {
    
    
            File file=new File("data.txt");
            fr=new FileWriter("hello.txt");

            fr.write("I");
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            try {
    
    
                fr.close();
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
    }

2.4FileInputStrem&&GFileOutputStream(字节流 节点流)

用于字节流数据的输入与输出

//实现一个视频文件的复制
@Test
    public void copy(String srcPath,String desPath){
    
    
        FileInputStream fi= null;
        FileOutputStream fo= null;
        try {
    
    
            fi = null;
            fo = null;

            File file_1=new File(srcPath);
            File file_2=new File(desPath);

            fi=new FileInputStream(file_1);
            fo=new FileOutputStream(file_2);
            byte [] buffer=new byte[1024];
            int len;
            while((len=fi.read(buffer))!=-1){
    
    
                fo.write(buffer,0,len);
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            try {
    
    
                fi.close();
                fo.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }         
        }
    }

2.6BufferedReader&&BufferedWriter(字符流、处理流)

 @Test
    public void testBufferedReaderBufferedWriter(){
    
    
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
    
    
            //创建文件和相应的流
            br = new BufferedReader(new FileReader(new File("dbcp.txt")));
            bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));

            //读写操作
            //方式一:使用char[]数组
//            char[] cbuf = new char[1024];
//            int len;
//            while((len = br.read(cbuf)) != -1){
    
    
//                bw.write(cbuf,0,len);
//    //            bw.flush();
//            }

            //方式二:使用String
            String data;
            while((data = br.readLine()) != null){
    
    
                //方法一:
//                bw.write(data + "\n");//data中不包含换行符
                //方法二:
                bw.write(data);//data中不包含换行符
                bw.newLine();//提供换行的操作

            }


        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //关闭资源
            if(bw != null){
    
    

                try {
    
    
                    bw.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(br != null){
    
    
                try {
    
    
                    br.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }

    }

2.5BufferedInputStream&&BufferedOutputStream(字节流、处理流)

@Test
    public void BufferedStreamTest() throws FileNotFoundException {
    
    
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
    
    
            //1.造文件
            File srcFile = new File("爱情与友情.jpg");
            File destFile = new File("爱情与友情3.jpg");
            //2.造流
            //2.1 造节点流
            FileInputStream fis = new FileInputStream((srcFile));
            FileOutputStream fos = new FileOutputStream(destFile);
            //2.2 造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[10];
            int len;
            while((len = bis.read(buffer)) != -1){
    
    
                bos.write(buffer,0,len);

//                bos.flush();//刷新缓冲区

            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //4.资源关闭
            //要求:先关闭外层的流,再关闭内层的流
            if(bos != null){
    
    
                try {
    
    
                    bos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
            if(bis != null){
    
    
                try {
    
    
                    bis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
            //说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
//        fos.close();
//        fis.close();
        }

2.6转换流

  • 1.转换流:属于字符流

  • InputStreamReader:将一个字节的输入流转换为字符的输入流

  • OutputStreamWriter:将一个字符的输出流转换为字节的输出流

  • 2.作用:提供字节流与字符流之间的转换

//将一个字节的输入流转换为字符的输入流
@Test
    public void test1() throws IOException {
    
    

        FileInputStream fis = new FileInputStream("dbcp.txt");
//        InputStreamReader isr = new InputStreamReader(fis);//使用系统默认的字符集
        //参数2指明了字符集,具体使用哪个字符集,取决于文件dbcp.txt保存时使用的字符集
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");//使用系统默认的字符集

        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
    
    
            String str = new String(cbuf,0,len);
            System.out.print(str);
        }

        isr.close();

2.7对象流

基本概念:
在这里插入图片描述
总结一句话,对象流就是把我们创建的对象通过序列化写入到数据集,并且也可以将对象通过反序列化从数据源中还原回来。

  • 对象流的使用

  • 1.ObjectInputStream 和 ObjectOutputStream

  • 2.作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

  • 3.要想一个java对象是可序列化的,需要满足相应的要求。见Person.java

  • 4.序列化机制:

  • 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种

  • 二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。

  • 当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
    具体如何序列化

public class ObjectInputOutputStreamTest {
    
    

    /*
    序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
    使用ObjectOutputStream实现
     */
    @Test
    public void testObjectOutputStream(){
    
    
        ObjectOutputStream oos = null;

        try {
    
    
            //1.
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //2.
            oos.writeObject(new String("我爱北京天安门"));
            oos.flush();//刷新操作

            oos.writeObject(new Person("王铭",23));
            oos.flush();

            oos.writeObject(new Person("张学良",23,1001,new Account(5000)));
            oos.flush();

        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(oos != null){
    
    
                //3.
                try {
    
    
                    oos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }

    }

    /*
    反序列化:将磁盘文件中的对象还原为内存中的一个java对象
    使用ObjectInputStream来实现
     */
    @Test
    public void testObjectInputStream(){
    
    
        ObjectInputStream ois = null;
        try {
    
    
            ois = new ObjectInputStream(new FileInputStream("object.dat"));

            Object obj = ois.readObject();
            String str = (String) obj;

            Person p = (Person) ois.readObject();
            Person p1 = (Person) ois.readObject();

            System.out.println(str);
            System.out.println(p);
            System.out.println(p1);

        } catch (IOException e) {
    
    
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(ois != null){
    
    
                try {
    
    
                    ois.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }



    }

}

(三)网络编程

TCP与UDP的区别是什么?

3.1实现TCP的网络编程

  • 一、网络编程中有两个主要的问题:
    1.如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
    2.找到主机后如何可靠高效地进行数据传输
  • 二、网络编程中的两个要素:
    1.对应问题一:IP和端口号
    2.对应问题二:提供网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、物理+数据链路层)
  • 三、通信要素一:IP和端口号
  1. IP:唯一的标识 Internet 上的计算机(通信实体)
  2. 在Java中使用InetAddress类代表IP
  3. IP分类:IPv4 和 IPv6 ; 万维网 和 局域网
  4. 域名: www.baidu.com www.mi.com www.sina.com www.jd.com www.vip.com
  5. 本地回路地址:127.0.0.1 对应着:localhost
  6. 如何实例化InetAddress:两个方法:getByName(String host) 、 getLocalHost()
    两个常用方法:getHostName() / getHostAddress()
  7. 端口号:正在计算机上运行的进程。
    要求:不同的进程有不同的端口号
    范围:被规定为一个 16 位的整数 0~65535。
  8. 端口号与IP地址的组合得出一个网络套接字:Socket

创建一个客户端和服务端 实现客户端向服务端发送数据 并且在客户端回显

package com.sgyj.Internet;

import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPTest {
    
    
    @Test
    //创建一个客户端和服务端 实现客户端向服务端发送数据 并且在客户端回显
    public void client() {
    
    

        Socket s1= null;
        OutputStream o1= null;
        try {
    
    
            s1 = null;
            o1 = null;
            //创建socket对象 指明服务器的IP和端口号
            InetAddress inetAddress=InetAddress.getByName("127.0.0.1");
            s1=new Socket(inetAddress,8844);
            //获取一个输出流,表示输出的数据
            o1=s1.getOutputStream();
            o1.write("我是一个好人".getBytes());
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if(o1!=null){
    
    
                try {
    
    
                    o1.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(s1!=null){
    
    
                try {
    
    
                    s1.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }

        }
    }
    @Test
    public void server(){
    
    
        ServerSocket ss=null;
        Socket socket=null;
        InputStream is=null;
        //创建服务器段的ServerSocket 表明端口
        try {
    
    
            ss=new ServerSocket(8844);

            //调用accept来接受客户端的socket
            socket=ss.accept();

            //获取输入流
            is=socket.getInputStream();

            //显示输入
            byte buffer []=new byte[1024];
            int len;
            while((len=is.read(buffer))!=-1) {
    
    
                String s=new String(buffer,0,len);
                System.out.println(s);
            }
            //4.读取输入流中的数据  防止乱码
            //baos = new ByteArrayOutputStream();
            //byte[] buffer = new byte[5];
            //int len;
            //while((len = is.read(buffer)) != -1){
    
    
            //    baos.write(buffer,0,len);
            //}
            //System.out.println(baos.toString());
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        finally {
    
    
            if(is!=null){
    
    
                try {
    
    
                    is.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(socket!=null){
    
    
                try {
    
    
                    socket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(ss!=null){
    
    
                try {
    
    
                    ss.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

3.2实现UDP的网络编程

package com.atguigu.java1;

import org.junit.Test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * UDPd协议的网络编程
 * @author shkstart
 * @create 2019 下午 4:34
 */
public class UDPTest {
    
    

    //发送端
    @Test
    public void sender() throws IOException {
    
    

        DatagramSocket socket = new DatagramSocket();



        String str = "我是UDP方式发送的导弹";
        byte[] data = str.getBytes();
        InetAddress inet = InetAddress.getLocalHost();
        DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);

        socket.send(packet);

        socket.close();

    }
    //接收端
    @Test
    public void receiver() throws IOException {
    
    

        DatagramSocket socket = new DatagramSocket(9090);

        byte[] buffer = new byte[100];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);

        socket.receive(packet);

        System.out.println(new String(packet.getData(),0,packet.getLength()));

        socket.close();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44020747/article/details/121152416