第16、19、20、22章学习
第16章 输入输出
stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。在Java的IO中,所有的stream(包括Inputstream和Out stream)都包括两种类型:
(1)字节流
表示以字节为单位从stream中读取或往stream中写入信息,即io包中的inputstream类和outputstream类的派生类。通常用来读取二进制数据,如图象和声音。
(2)字符流
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream中写入信息。
-
一.流的层次结构
定义:
(1) java将读取数据对象成为输入流,能向其写入的对象叫输出流。结构图如下: -
二.InputStream类
inputstream类和outputstream类都为抽象类,不能创建对象,可以通过子类来实例化。
InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:
(1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。
(2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
(3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
(4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
(5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
(6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭. -
三.OutputStream类
OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。
1. public void write(byte b[ ]):将参数b中的字节写到输出流。
2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。
3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。
4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。
5. public void close( ) : 关闭输出流并释放与流相关的系统资源。
注意:
1. 上述各方法都有可能引起异常。
2. InputStream和OutputStream都是抽象类,不能创建这种类型的对象。 -
四.FileInputStream类
FileInputStream类是InputStream类的子类,用来处理以文件作为数据输入源的数据流。 -
五.FileOutputStream类
FileOutputStream类用来处理以文件作为数据输出目的数据流;一个表示文件名的字符串,也可以是File或FileDescriptor对象。 -
六.File类
File类与InputStream / OutputStream类同属于一个包,它不允许访问文件内容。
File类主要用于命名文件、查询文件属性和处理文件目录。 -
七.从一个流构造另一个流
java的流类提供了结构化方法,如,底层流和高层过滤流。
而高层流不是从输入设备读取,而是从其他流读取。同样高层输出流也不是写入输出设备,而是写入其他流。
使用”分层对象(layered objects)”,为单个对象动态地,透明地添加功能的做法,被称为Decorator Pattern。Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得decorator的用法变得非常的透明–无论对象是否被decorate过,传给它的消息总是相同的。这也是Java I/O类库要有”filter(过滤器)”类的原因:抽象的”filter”类是所有decorator的基类。Decorator模式常用于如下的情形:如果用继承来解决各种需求的话,类的数量会多到不切实际的地步。Java的I/O类库需要提供很多功能的组合,于是decorator模式就有了用武之地。
第19章 线程
Java线程:创建与启动
- 一、定义线程
1、扩展java.lang.Thread类。
此类中有个run()方法,应该注意其用法:
public void run()
如果该线程是使用独立的Runnable运行对象构造的,则调用该Runnable对象的run方法;否则,该方法不执行任何操作并返回。
Thread的子类应该重写该方法。
2、实现java.lang.Runnable接口。
void run()
使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的run方法。
方法run的常规协定是,它可能执行任何所需的操作。
- 二、实例化线程
1、如果是扩展java.lang.Thread类的线程,则直接new即可。
2、如果是实现了java.lang.Runnable接口的类,则用Thread的构造方法:
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
- 三、启动线程
在线程的Thread对象上调用start()方法,而不是run()或者别的方法。
在调用start()方法之前:线程处于新状态中,新状态指有一个Thread对象,但还没有一个真正的线程。
在调用start()方法之后:发生了一系列复杂的事情
启动新的执行线程(具有新的调用栈);
该线程从新状态转移到可运行状态;
当该线程获得机会执行时,其目标run()方法将运行。
注意:对Java来说,run()方法没有任何特别之处。像main()方法一样,它只是新线程知道调用的方法名称(和签名)。因此,在Runnable上或者Thread上调用run方法是合法的。但并不启动新的线程。
第20章 并发工具
1.原子操作:java.util.concurrent.atomic类中提供了很懂很多原子类,如:AtomicBoolean,atomicInteger
2.Excutor、ExcutorService
Excutor中由于各有一个excute()函数相当于thread中的run
ExcutorService是Excutor的一个子集
ExcutorService中一个比价重要的方法是public static ExcutorService newFixedThreadPool(int numofThreads)(注意:这是Excutors工具类中的一个静态函数)
第22章 网络
计算机网路实现了多个网络终端的互联,彼此之间能够进行数据交流。而网络应用程序就是在已连接的不同终端设备上运行的程序,这些网络程序相互之间可以进行数据交互。网络程序的数据交互则依赖于TCP/IP协议,在实际应用中TCP网络程序提供可靠的数据通信,而UDP网络程序则不保证数据的可靠性,但是协议简单、传输速度快(比如用在音视频数据传输,它们不需要很高的可靠性,偶尔丢帧是可以忍受的)。
ServerSocket类
Java.net包中的ServerSocket类用于表示服务器套接字,其主要功能是监听客户端的请求,然后将客户端的请求连接存入队列中,默认请求队列大小是50。构造方法主要有以下几种形式:
ServerSocket():创建非绑定服务器套接字。
ServerSocket(int port):创建绑定到特定端口的服务器套接字。
ServerSocket(int port,int backlog):利用指定的backlog创建服务器套接字并将其绑定到指定的本地端口号。
ServerSocket(int port,int backlog,InetAdress bindAddress):使用指定的端口、监听backlog和要绑定到本地IP地址创建服务器,适用于计算机有多个网卡、多个IP的情景。
UDP网络程序
使用UDP协议的程序流程简单很多,它收发包流程如下:
UDP网络通信的发包过程:
使用DatagramSocket()创建一个数据包套接字。
使用DatagramPacket(byte[]buf,int offset,int length,InetAddress address,int port)创建要发送的数据包。
使用DatagramSocket类的send()方法数据包。
UDP网络通信的收包过程:
使用DatagramSocket()创建一个数据包套接字,绑定到指定的端口。
使用DatagramPacket(byte[]buf,int length)创建字节数组来接收数据包.
使用DatagramPacket类的receive()方法接收UDP。