core java--day21(随机访问流 : RandomAccessFile,序列化:利用ObjectOutputStream将对象输出,网络通信,基于TCP的Socket服务器程序编写)

复习:


PipedInputStream :
    多线程  流  数据交互
PipedOutputStream:
    
    PIS pis= new PIS();
    POS pos = new POS(pis);

    pis.connect(pos);
    pos.connect(pis);
包装流

BufferedInputStream :
BufferedOutputStream:
    缓冲区 : byte[]
     提高读取写入速度,减少io操作

    FileInputStream fis = new FIS();
    BufferedInputStream bis = new BIS(fis);
    
    FileOutputStream fos = new FOS();
    BufferedOutpuStream bos = new BOS(fos);

包装流  :  字节包装流
DataInputStream:
DataOutputStream:


    byte    1字节     8位
    short   2字节    16位
    int     4字节    32位
    long    8字节    64位
    float   4字节    32位
    double  8字节    64位
    char    2字节    16位
    boolean 1字节   8位
        1-->true
        0-->false

8L
(0000 0000) (0000 0000) (0000 0000) (0000 0000)    
(0000 0000) (0000 0000) (0000 0000) (0000 1000)

writeLong(8L);

readBoolean();      0 false 
readByte();         0
readShort();        0
readBoolean();        0 false
readInt();        EOFException  编译异常


writeBooelean();

readBoolean();

一个文件就写一个数据
    写int/long/double/boolean....

PrintStream : 打印流
   println();
   print();
   printf();

System.out.println();

Reader : 
Writer :

CharArrayReader : 字符输入流
    读取字符
CharArrayWriter : 字符输出流
    字符数组
    char[]
    caw.toCharArray();
    caw.toString();

文件字符流
FileReader
FileWriter
    fw.append().append().append();
    fw.flush();

包装 : 字符包装流
BufferedReader :
    readLine();
PrintWriter    :
    FileReader fr = new FR();
    BufferedReader br = new BR(fr);
    
    PrintWriter pw = new PW(File);
    PrintWriter pw = new PW("fileName","GBK");
    PrintWriter pw = new PW(out);

    
    覆盖
    PrintWriter pw = new PW("a.txt");
    追加
    FileOutputStream fos = new FOS("a.txt",true);
    PrintWriter pw = new PW(fos);
    编码+追加
    FileOutputStream fos = new FOS("a.txt",true);
    OutputStreamWriter osw = new OSW(fos,"UTF-8");
    PrintWriter pw = new PW(osw);
    
    pw.println("-------");


转换流 :  字节流 转换为 字符流
【编码设置】
InputStreamReader
OutputStreamWriter

    FileInputStream fis= new FIS("a.txt");
    InputStreamReader isr = new ISR(fis);
    InputStreamReader isr = new ISR(fis,"UTF-8");

    FileOutputStream fos = new FOS("a.txt");
    OutputStreamWriter osw = new OSW(fos);
    OutputStreamWriter osw = new OSW(fos,"GBK");


3.11 :  随机访问流 :  RandomAccessFile
        特点:将文件中的数据全部读取到流中,对流可以一直反复操作。
        构造器:new RandomAccessFile(new File(),"r")--->只读方式("r")
        构造器:new RandomAccessFile(new File(),"rw")--->读写方式("rw")
    
         注意:利用readLine()读取得到的字符串是乱码。这是因为从文件中读取是以ISO-8859-1编码读取,如果是从文件中读取字符串需要转码操作。
             eg:  String msg = in.readLine();//你好
              String dat = new String(msg.getBytes("ISO-8859-1"));//你好
              将msg以ISO-8859-1编码转为字节数组,然后通过该字节数组得到String(当前文件编码)。
        utf-8占用字节:
            一个utf8数字占1个字节
            一个utf8英文字母占1个字节
            占2个字节的:〇
            占3个字节的:基本等同于GBK,含21000多个汉字
            占4个字节的:中日韩超大字符集里面的汉字,有5万多个
            
        主要操作
             3.11.1:seek()        定位,设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
             3.11.2:getFilePointer()    获得文件的当前偏移量
             3.11.3:skipBytes()        跳过多少字节数
             3.11.4:length()        文件大小
    
        详解:seek(index); 设置偏移量。
            eg: a.txt文件中 abc你  占6字节  seek(3),表示将偏移量设置到 abc|你  下次读取就是读取 你 的第一个字节
              getFilePointer();获得文件中的当前偏移量
            eg: a.txt文件中 abc你  占6字节 读取了3个字节,代表当前偏移量为3 返回为3。
              skipBytes(n);跳过n字节
            eg: a.txt文件中 abc你  占6字节, skipBytes(1)跳过一个字节,偏移量在当前位置+1。
    

package com.briup.ch21;

import java.io.RandomAccessFile;
import java.lang.ProcessBuilder.Redirect;

//随机访问流读取测试
public class Test2 {
	
	public static void main(String[] args) throws Exception {
		//随机访问 输入流
		RandomAccessFile in = 
				new RandomAccessFile("a.txt", "r");
		//读取
		int read = in.read();
		System.out.println(read);
		
		byte b = in.readByte();
		System.out.println(b);
		
		//回读第一个 字节
		//移动光标
		in.seek(0);
		System.out.println(in.readByte());
		in.seek(1);
		System.out.println(in.readByte());
		//跳过3个字节
		in.skipBytes(3);
		System.out.println(in.readByte());
		
		//获得当前文件的长度
		long length = in.length();
		
		//读取到空格 记录 空格的位置
		for(int i= 0;i<length-in.getFilePointer();i++) {
			//读取的字节数据
			byte readByte = in.readByte();
			
			if(readByte==32) {
				//打印空格在的位置
				//获得当前光标的位置
				long filePointer = in.getFilePointer();
				System.out.println("\t"+filePointer);
			}
			System.out.println(readByte);
			Thread.sleep(500);
		}
	}
	
}
package com.briup.ch21;

import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;

//随机访问流 使用 14
public class Test3 {
	public static void main(String[] args) throws Exception {
		//随机访问流  读
		RandomAccessFile raf = 
				new RandomAccessFile("a.txt", "r");
		//-开始的位置
		long start = 0;
		//-结束的位置
		long end = 0;
		
		//循环读   - 45
		for(int i= 0;i<raf.length();i++) {
			byte readByte = raf.readByte();
			if(readByte==45 && start==0) {//开始位置
				//记录位置
				//获取当前位置
				long filePointer = raf.getFilePointer();
				//当前位置赋值给 start
				start = filePointer;
			}else if(readByte==45 && start!=0) {
				//读取到结束的 -
				//记录位置
				long filePointer = raf.getFilePointer();
				end = filePointer;
			}
			//System.out.println(readByte);
		}//循环end  -开始和 结束位置都成功获取
		
		//光标移动到开始位置
		raf.seek(start);
		//开始读取数据,读end-start
		
		byte[] but = new byte[(int) (end-start-1)];
		//读取 end-start个长度的 字节数组,
		//数据 放到了 字节数组中
		raf.read(but);
		
		
		raf.readLine();
		
		//字节数组 转换为 字符串
		String msg = new String(but);
		System.out.println("最终获取的数据  :  "+msg);
		
		
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("name", "tom");
		

		raf.close();
	}
}


四,IO流 对象序列化和反序列化
    4.1:序列化:利用ObjectOutputStream 将对象输出流 将对象写到文件中。
        在利用ObjectOutputStream写对象到文件的过程中, 
        eg1:ObjectOutputStream oos = new ObjectOutputStream(文件,追加);
           oos.writeObject(对象1);
           oos.writeObject(对象2);
           oos.writeObject(对象3);
        得到文件:
           标记对象1对象2对象3
        eg2:
           上面代码执行两次
        得到文件:
            标记对象1对象2对象3标记对象1对象2对象3
    
    4.1:反序列化:利用ObjectInputStream将对象从文件中读取到流中。
        在利用ObjectInputStream将文件中的对象读取过来的时候。
        eg11:读取上eg1 所产生的文件
           ObjectInputStream ois = new ObjectInputStream(文件);
           ois.readObejct();
           ois.readObject();
           ois.readObject();
        得到3个对象
        eg22:读取上eg2所产生的文件
           ObjectInputStream ois = new ObjectInputStream(文件);
           ois.readObejct();
           ois.readObject();
           ois.readObject();
           ois.readObject();
           ois.readObject();
           ois.readObject();
         得到:---> 报错-->因为连续读取了6个对象,但是eg2文件中是 标记3对象标记3对象 在读取到第四个对象的时候会报错,readObject 读取到的是标记。
         改:
           ObjectInputStream ois = new ObjectInputStream(文件);
           ois.readObejct();
           ois.readObject();
           ois.readObject();
           ois = new ObjectInputStream(文件);//因为在调用构造器的时候回读取 标记
           ois2.readObejct();
           ois2.readObject();
           ois2.readObject();
         得到 6对象
    
    注意:对象的序列化和反序列化操作的对象一定要实现Serializable接口。(这是空接口,只是一个标识);

package com.briup.ch21;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ReadOnlyBufferException;
import java.util.Arrays;

//读取对象 和 写入对象
public class Test4 {

	public static void main(String[] args) throws Exception {
		//writer();
		read();
	}
	
	public static void read()throws Exception {
		FileInputStream fis= new FileInputStream("a.txt");
		//创建输入流的时候会读取 【头】
		ObjectInputStream ois = 
				new ObjectInputStream(fis);
		//本次读取的数据 本质类型就是数组,
		//所以强转为 数组类型
		//int[] arr = (int[]) ois.readObject();
		//System.out.println(Arrays.toString(arr));
		
		System.out.println(ois.readObject());
		System.out.println(ois.readObject());
			//创建输入流的时候会读取 【头】
			ois = new ObjectInputStream(fis);
		System.out.println(ois.readObject());
		System.out.println(ois.readObject());
		//多度一个对象
		//System.out.println(ois.readObject());
	}
	
	
	public static void writer()throws Exception {
		FileOutputStream fos = 
				new FileOutputStream("a.txt");
		
		//构建对象输出流
		
		//对象
		int[] arr = {1,2,3,4,5};
		String msg = new String("hello");
		
		
		
		//创建输出流的时候会写【头】
		ObjectOutputStream oos = 
				new ObjectOutputStream(fos);
		//oos.writeObject(arr);
		oos.writeObject(msg);
		oos.writeObject(msg);
			//重新赋值
			//创建输出流的时候会写【头】
			oos = new ObjectOutputStream(fos);
		oos.writeObject(msg);
		oos.writeObject(msg);
		
		//oos.writeObject(10);
		//oos.writeObject(true);
		
		oos.flush();
		oos.close();
		fos.close();
	}
}
package com.briup.ch21;

import java.io.Serializable;

import lombok.Data;

@Data
public class Student implements Serializable{

	private Integer id;
	private String name;
	
	public Student() {}

	public Student(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
}

package com.briup.ch21;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

//测试 对象流 写 Student对象  31
public class Test5Student {
	public static void main(String[] args) throws Exception {
		FileOutputStream fos = 
				new FileOutputStream("a.txt");
		ObjectOutputStream oos =
				new ObjectOutputStream(fos);
		//构建自定义对象Student
		Student s1 = new Student(1,"tom");
		oos.writeObject(s1);
		
		//写5个Student
		List<Student> list= new ArrayList<Student>();
		list.add(new Student(2,"tom2"));
		list.add(new Student(3,"tom3"));
		list.add(new Student(4,"tom4"));
		list.add(new Student(5,"tom5"));
		//直接写list集合
		oos.writeObject(list);
		
		oos.flush();
		oos.close();
		fos.close();
		
		//读取数据
		FileInputStream fis = new FileInputStream("a.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		
		Student stu = (Student) ois.readObject();
		System.out.println(stu.getId());
		System.out.println(stu.getName());
		
		List<Student> stus = (List<Student>) ois.readObject();
		for(Student s : stus) {
			System.out.println("------------");
			System.out.println(s.getId());
			System.out.println(s.getName());
		}

		
	}
}

网络编程:
1,计算机网络
    计算机网络是相互连接的独立自主的计算机的集合,
    最简单的网络形式由两台计算机组成。

       127.220.0.1
    0000 0000 255
2,网络通信
       2.1 : IP地址:
    IP网络中每台主机都必须有一个惟一的IP地址;
    IP地址是一个逻辑地址;
    因特网上的IP地址具有全球唯一性;
    32位,4个字节,常用点分十进制的格式表示,例如:192.168.0.16。
       2.2 : 端口号:
    端口使用一个16位的数字来表示,
    它的范围是0--65535,
    1024以下的端口号保留给预定义的服务。
    例如:http使用80端口。
    

3 , 基于TCP的Socket编程步骤:
    传输层:
       TCP:面向连接的可靠的传输协议;
         在利用TCP协议进行通信的时候,
         首先要经过三步握手建立起通信双方的连接,
         一旦连接建立后就可以通信了。
         TCP协议提供数据确认和重传的机制,
         保证数据一定能够到达数据接收端。
         像打电话。

    服务器端:被操作
    客户端:用来操作服务器

  常见的架构:网络编程

    QQ     客户端   服务器
    网页小游戏            服务器
    
    C/S  :客户端 + 服务器
    B/S  : 浏览器 + 服务器
            javaEE
 3.1 : 服务器程序编写:
        1,调用ServerSocket(int port)创建一个服务器端套接字,并绑定到指定端口上;
        2,调用accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字;
        3,调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收;
        4,最后关闭通信套接字

package com.briup.ch21.t1;

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

//我的服务器
public class MyServer1 {
	public static void main(String[] args) throws Exception {
		
		//ServerSocket 只需要创建这个类的对象
		System.out.println("创建成功");
		//127.0.0.1 8099
		//window :cmd中输入 ipconfig 当前电脑的ip地址
		//linux  :ifconfig 当前电脑的ip地址
		ServerSocket server 
			= new ServerSocket(8099);
		while(true) {
			//服务器监听是否有客户端的访问
			Socket socket = server.accept();//会阻塞
			//获得链接过来的客户端 ip地址
			InetAddress inetAddress = socket.getInetAddress();
			System.out.println(inetAddress);
			
			//获得和当前客户端连接的输出流
			//服务器吧数据输出到客户端
			OutputStream out = socket.getOutputStream();
			out.write(inetAddress.toString().getBytes());
			out.flush();
			
			//获得和当前客户端连接的输入流
			//服务器从客户读入数据
			InputStream in = socket.getInputStream();
			
			out.close();
			socket.close();
		}
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值