20169221 2016-2017-2 《移动平台应用与开发》第五周学习总结

第十六章 输入输出

文件系统和路径

文件系统包含3种类型的对象:文件、目录、符号连接
FileSystem表示一个文件系统是一个抽象类,静态方法getDefault返回当前文件系统html

FileSystem fileSystem=FileSystems.getDefault();

文件目录和处理的操做

1.建立和删除文件和目录
删除文件时,若是path是一个目录,目录必须为空,若是是一个符号连接,只有连接会被删除,而且没有链接目标,若是path不存在则会抛出一个NoSsuchFileException
2.复制和移动文件夹
CopyOption是java。nio.file中的一个接口
ATOMIC_MOVE:移动文件做为一个基本的文件系统操做
COPY_ATTRIBUTES:将属性复制到新的文件夹
REPLACE_EXISTING:java

输入/输出流

java.io包中的四个抽象类android

  • Reader
  • Writer
  • InputStream
  • OutStream
    流的好处是无论什么数据源和目标均可以使用。
    操做顺序:1)建立一个流。2)执行读取写入操做。3)调用流的close方法来关闭流。web

    读写二进制数据

    1.读二进制数据
    InputStream能够从池中读取一个二进制数据。
    因为File.newInputStream没有缓存,可使用BufferedInputStream包装以达到更好的性能。
Path path = ...
try (InputStream inputStream = Files.newInputStream(path,
StandardOpenOption.READ;
BufferedInputStream buffered =
new BufferedInputStream(inputStream)) {
// manipulate buffered, not inputStream
} catch (IOException e) {
// do something with e
}

Input类使用一个内部指针,指向读取数据开始的位置。每个重载的read方法都有返回所读取的字节数,若是没有数据读入到InputStream,返回-1.
2.写二进制数据
OutputStream将二进制数据写入池中一个流。
因为File.newOutputStream没有缓存,可使用BufferedOutputStream包装以达到更好的性能数据库

Path path = ...
try (OutputStream outputStream = Files.newOututStream(path,
StandardOpenOption.CREATE, StandardOpenOption.APPEND;
BufferedOutputStream buffered =
new BufferedOutputStream(outputStream)) {
// manipulate buffered, not outputStream
} catch (IOException e) {
// do something with e
}

写文本

1.Write和OutputStream相似,不过它出路的是字符而不是字节
2.OutStreamWriter:是字符流和字节流之间的桥梁,可以将Unicode转化为byte表示。浏览器

OutputStream os = Files.newOutputStream(path, openOption);
OutputStreamWriter writer = new OutputStreamWriter(os, charset);

3.PrintWriter容许经过给其构造方法传入编码信息,它更易使用,由于它添加了9种重载方式能够打印任意类型的java基本类型和对象。
可使用bufferwriter将一个write包装起来以获得更好的性能,可是bufferwriter不能这么包装。缓存

PrintWriter printWriter = ...;
BufferedWriter bw = new BufferedWriter(printWriter);

读文本

1.Reader:读取字符的输入流
2.InputStreamReader:读取字节,并使用指定字符集将其转换为字符。
3.BufferedReader:包装另外一个Reader,并提供一个缓存。提取一个readLine方法来读取一行文本。服务器

随机访问文件

1.对于 FileInputStream/FileOutputStream、FileReader/FileWriter 来讲,它们的实例都是顺序访问流,即只能进行顺序读/写。而类 RandomAccessFile 则容许文件内容同时完成读和写操做,它直接继承 object,而且同时实现了接口 DataInput 和 DataOutput,提供了支持随机文件操做的方法:
readXXX()或者 writeXXX():如 ReadInt(),ReadLine(),WriteChar(),WriteDouble()等
int skipBytes(int n):将指针向下移动若干字节
length():返回文件长度
long getFilePointer():返回指针当前位置
void seek(long pos):将指针调用所需位置网络

对象序列化

ObjectOutputStream:建立一个ObjectOutputStream类以后能够序列化对象和基本类型。多线程

public void writeBoolean(boolean value)
public void writeByte(int value)
public void writeBytes(String value)
public void writeChar(int value)
public void writeChars(String value)
public void writeDouble(double value)
public void writeFloat(float value)
public void writeInt(int value)
public void writeLong(long value)
public void writeShort(short value)
public void writeObject(java.lang.Object value)

若是一个序列化对象包含其余的对象,被包含对象必须实现Serializable。这样被包含对象才是可序列化的。
对象序列化是一个先进后出的方法,先序列化的对象,必须是最后解序列化的

第十九章 线程

线程

线程是一个基本处理单元操做系统分配和处理的时间就是按照线程来劲心仪的。在一个进程中能够有多个线程执行代码,现成有时候也叫做一个轻量级进程,或者叫作一个执行环境。

建立一个线程

(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法能够抛出异常,run方法不能够
(4)运行Callable任务能够拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。经过Future对象能够了解任务执行状况,可取消任务的执行,还可获取执行结果。
一、经过实现Runnable接口来建立Thread线程:
  步骤1:建立实现Runnable接口的类:

  class SomeRunnable implements Runnable
  {
  public void run()
  {
  //do something here
  }
  }

  步骤2:建立一个类对象:

  Runnable oneRunnable = new SomeRunnable();

  步骤3:由Runnable建立一个Thread对象:

  Thread oneThread = new Thread(oneRunnable);

  步骤4:启动线程:
  oneThread.start(); 
注释:线程的执行流程很简单,当执行代码oneThread.start();时,就会执行oneRunnable对象中的void run();方法,该方法执行完成后,线程就消亡了。
二、与方法1相似,经过实现Callable接口来建立Thread线程:其中,Callable接口(也只有一个方法)定义以下:

  public interface Callable
  {
  V call() throws Exception;
  }

  步骤1:建立实现Callable接口的类SomeCallable(略);
  步骤2:建立一个类对象:

  Callable oneCallable = new SomeCallable();

  步骤3:由Callable建立一个FutureTask对象:

  FutureTask oneTask = new FutureTask(oneCallable);

注释:FutureTask是一个包装器,它经过接受Callable来建立,它同时实现了Future和Runnable接口。
  步骤4:由FutureTask建立一个Thread对象:
   Thread oneThread = new Thread(oneTask); 
 步骤5:启动线程:

  oneThread.start();

三、经过继承Thread类来建立一个线程:
  步骤1:定义一个继承Thread类的子类:

  class SomeThead extends Thraad
  {
  public void run()
  {
  //do something here
  }
  }

  步骤2:构造子类的一个对象:
  SomeThread oneThread = new SomeThread(); 
  步骤3:启动线程

使用多线程

咱们可使用多线程.

package app19;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ThreadDemo3 extends JFrame {
JLabel countUpLabel = new JLabel("Count Up");
JLabel countDownLabel = new JLabel("Count Down");
class CountUpThread extends Thread {
public void run() {
int count = 1000;
while (true) {
try {
sleep(100);
} catch (InterruptedException e) {
}
if (count == 0)
count = 1000;
countUpLabel.setText(Integer.toString(count--));
}
}
}
class CountDownThread extends Thread {
public void run() {
int count = 0;
while (true) {
try {
sleep(50);
} catch (InterruptedException e) {
}
if (count == 1000)
count = 0;
countDownLabel.setText(Integer.toString(count++));
}
}
}
public ThreadDemo3(String title) {
super(title);
init();
}
private void init() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(new FlowLayout());
this.add(countUpLabel);
this.add(countDownLabel);
this.pack();
this.setVisible(true);
new CountUpThread().start();
new CountDownThread().start();
}
private static void constructGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
ThreadDemo3 frame = new ThreadDemo3("Thread Demo 3");
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
constructGUI();
}
};
}
}

线程优先级

若是在应用程序中有多个程序在运行,但一些线程比另外一些重要于是须要分配更多的CPU时间的状况下,能够在一个进行中为不一样的线程指定不一样的优先级。通常状况下,若是有优先级较高的线程在工做,就不会给优先级较低的线程分配任什么时候间片,其优势是能够保证给接收用户输入的线程指定较高的优先级。在大多数的时间内,这个线程什么也不作。而其余线程则执行它的任务。可是,若是用户输入了信息,这个线程就会当即得到比应用程序中其余线程更高的优先级,在短期内处理用户输入数据。
设置进程优先级要使用

public final void setPriority(int priority)

线程的优先级及其含义
Highest
将线程安排在具备任何其余优先级的线程以前
AboveNormal
将线程安排在具备Highest优先级的线程以后,在具备Normal优先级的线程以前
Normal
将线程安排在具备AboveNormal优先级的线程以后,在具备BelowNormal优先级的线程以前。默认状况下,线程具备Normal优先级
BelowNormal
将线程安排在具备Normal优先级的线程以后,在具备Lowest优先级的线程以前
Lowest
将线程安排在具备任何其余优先级的线程以后
__Java多线程 -- 线程的优先级

中止线程

Thread有一个stop的方法来中止一个线程。中止一个线程时候应该让run方法天然退出,直接让条件计算为假便可。

boolean condition = true;
public void run {
while (condition) {
// do something here
}
}
In your class, you also need to provide a method to change the value of condition.
public synchronized void stopThread() {
condition = false;
}

同步

使用线程的一个重要内容是同步访问多个线程访问的任何变量。所谓同步,是指在某一时刻只有一个线程能够访问变量。若是不能确保对变量的访问是同步的,就可能会产生错误或不可预料的结果。通常状况下,当一个线程写入一个变量,同时有其余线程读取或写入这个变量时,就应同步变量。经过指定对象的加锁和解锁能够同步代码段的访问。在.NET的System.Threading命名空间中提供了Monitor类来实现加锁与解锁。这个类中的方法都是静态的,因此不须要实例化这个类。下表中一些静态方法提供了一种机制用来向同步对象的访问从而避免死锁和维护数据一致性。
1.线程干扰:假设一个线程读取了userCount的值并增长它,在它有机会将增长后的值存储回去以前,另外一个线程读取它并获得了旧的值。当第二个线程最终获得机会写userCount时,他会替代第一个线程增长后的值。结果,userCount并无反映西湖正确的用户数目,一个事件有两个非原子性操做在不一样线程中进行。
2.原子操做:组合起来可让系统其余部分将其当作一个单个操做的一组操做,不会用法线程干扰
3.方法同步:Jav对象都有一个内在的锁。获取一个对象内在的锁是一种独占是的访问一个对象的方法。试图访问一个度一项线程将会被阻塞,直到持有锁的线程释放该锁。
当线程执行到synchronized的时候,若是得不到锁标记,这个线程会被加入到一个与该对象的锁标记相关连的等待线程池当中,等待锁标记。当线程执行完同步代码,就会释放锁标记。一个刚释放了锁标记的线程能够立刻再次得到锁标记,当同步块遇到break或抛出exception时,线程也会释放锁标记。
4.块同步:同步块给了你一个对象的内在锁在块中代码执行以后释放该锁。

线程协调

当方法体或代码块被synchronized方法修饰时,有一个线程在执行这部分代码时,其它线程没法同时执行这部分代码。在Java中,有三个方法能够对线程进行主动高效的控制,它们是wait,notify和notifyAll。wait是主动让线程等待的方法,而notify和notifyAll则是激活等待中的线程的方法。他们都是Object类的方法,也就是说任何对象均可以使用这三个方法。
1) wait,notify和notifyAll都是java.lang.Object的方法,它们用来对线程进行调度.
2) obj.wait()是把执行这句的线程放入obj的wait set中.
3) obj.notify()是从wait set中唤醒一个线程,这个线程在当前线程释放对obj的锁定后即获取这个锁定.
4) obj.notifyAll()是唤醒全部在obj的wait set中的线程,这批线程在当前线程释放obj的锁定后去竞争这个锁定,最终只有一个能得到,其它的又从新返回wait set等待下一次激活.
5) 执行这个wait,notify和notifyAll这三个方法前,当前线程(即执行obj.wait(), obj.notify()和obj.notifyAll()代码的线程)必须持有obj的锁定.

第二十二章 网络

超文本传输协议

HTTP是容许Web服务器和浏览器之间经过互联网发送和接收数据的协议。
1.HTTP请求:一次HTTP请求包括方法、请求头和请求实体

POST /examples/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US;
rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
lastName=Franks&firstName=Michael

2.HTTP响应:包括三部分协议-状态码-说明、响应头、响应实体。

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Date: Thu, 12 Aug 2010 13:13:33 GMT
Content-Type: text/html
Last-Modified: Thu, 5 Aug 2010 13:13:12 GMT
Content-Length: 112
<html>
<head>
<title>HTTP Response Example</title>
</head>
<body>
Welcome to Brainy Software
</body>
</html>

java.net.URL

1.URL是互联网资源惟一的地址,它是指向互联网“资源”的指针。资源能够是简单的文件或目录,也能够是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。 简单的能够把URL理解为包含:协议、主机名、端口、路径、查询字符串和参数等对象。每一段能够独立设置。
相对 URL 不须要指定 URL 的全部组成部分。若是缺乏协议、主机名称或端口号,这些值将从完整指定的 URL 中继承。
调用URL类来构建URL

public URL(java.lang.String spec)
public URL(java.lang.String protocol, java.lang.String host,
java.lang.String file)
public URL(java.lang.String protocol, java.lang.String host,
int port, java.lang.String file)
public URL(URL context, String spec)

2.解析URL

public java.lang.String getFile()
public java.lang.String getHost()
public java.lang.String getPath()
public int getPort()
public java.lang.String getProtocol()
public java.lang.String getQuery()

3.读取web资源

public final java.io.InputStream openStream()
throws java.io.IOException

java.net.URLConnection

1.读取web资源
2.写一个到web服务器
在请求发送以前,HttpURLConnetion会把全部须要发送的数据放到缓冲区里,无论你是否使用connection.setRequestProperty(“Content-Length”, contentLength);设置contentLength,当你并行发送大量的POST请求时,这可能会引发OutOfMemoryExceptions 异常,为了不这个问题,你须要使HttpURLConnection.setFixedLengthStreamingMode()方法。可是若是不能事先知道内容的长度,可使用HttpURLConnection.setChunkedStreamingMode()方法设置为块状流模式。在块状流模式的状况下,放在块里的内容将会被强行发送出去。下边的例子将会把发送的内容按照每块1KB的大小发送出去。

java.net.Scoket

套接字是的应用程序可以从网络打野去呀或者从网络写入信息。
成功喜欢简Socket类一个实例后可使用它发送或者接受字节流

java.net.SeverScoket

Socket是一个“客户端”套接字,想要实现一个女远程服务,须要使用java.net.ServerSocket类。他是服务器套接字的一个实现
构造方法

public ServerSocket(int port, int backLog,
InetAddress bindingAddress);

有了ServerSocket,可让它在服务器套接字监听端口上等待对绑定地址的一个乳香链接请求

遇到的问题

class First extends Thread
{
    public First()
    {
        start();
    }
     
    synchronized public void run()
    {
        try
        {
            wait();
        }
        catch(InterruptedException e)
        {
            e.printStackTrace();
        }
        try
        {
            sleep(2000);
        }
        catch(InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println("hello world~");
    }
}
class Second extends Thread
{
    First first;
    public Second(First first)
    {
        this.first = first;
        start();
    }
     
    synchronized public void run()
    {
        try
        {
            wait();
        }
        catch (InterruptedException e1)
        {
            e1.printStackTrace();
        }
        synchronized( first )
        {
            try
            {
                sleep(2000);
                System.out.println("I'm faster than first~");
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
            first.notifyAll();
        }
    }
}
public class Main
{
    public static void main(String[] args) throws InterruptedException
    {
        First first = new First();
        Second second = new Second(first);
        synchronized( second )
        {
            System.out.println("I'm faster than second~");
            second.notifyAll();
        }
    }
}

问题:输出只有I'm faster than second~
缘由:在main函数中,对second.notifyAll()的调用早于second中的wait()调用(由于是多线程并行,故函数响应时间与代码前后顺序无关),这样先唤醒了second,紧接着second才开始wait,所以就处于无响应状态。
解决方法:只要在second.notifyAll()调用以前空出一点时间先让second的wait调用开始便可,事实上,这段时间如此之短以致于在我电脑上只须要在以前加一行输出语句便可。为了保险起见,仍是多加了个sleep
2.HTTP响应状态为4xx(客户端错误)或者5xx(服务器错误)
解决方法:你能够经过HttpUrlConnection.getErrorStream()来查看服务器发送过来的信息。

参考资料

java中常见的输入输出流案例学习
JAVA多线程与并发学习总结分析

代码提交截图

上周考试错题总结



博客评论

唐瑶5分
姚静5分

学习进度条

教材学习 视频学习 博客量(新增/累积) 重要成长
目标 16 19 22章 20篇
第五周 第16 19 22章 《Linux基础入门》 1/1 学习输入输出线程和网络
2/3
相关文章
相关标签/搜索