一、缓冲流

1.1、字符流的缓冲区

缓冲区的出现是为了提高IO的读写效率

对应类

BufferedReader

BufferedWriter

缓冲区要结合流才可以使用

在流的基础上对流的功能进行了增强

1.2、BufferedReader、BufferedWriter

public class BufferedWriterextends Writer

构造方法摘要
BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out,
int sz)


创建一个使用给定大小输出缓冲区的新缓冲字符输出流。

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。

该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。

通常 Writer 将其输出立即发送到底层字符或字节流。除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,

PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

将缓冲 PrintWriter 对文件的输出。如果没有缓冲,则每次调用 print() 方法会导致将字符转换为字节,然后立即写入到文件,而这是极其低效的。

public class BufferedReaderextends Reader

构造方法摘要
BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in,
int sz)

创建一个使用指定大小输入缓冲区的缓冲字符输入流。

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。例如,

BufferedReader in
= new BufferedReader(new FileReader("foo.in"));

将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。

通过用合适的 BufferedReader 替代每个 DataInputStream,可以对将 DataInputStream 用于文字输入的程序进行本地化

1.3、示例

在创建缓冲区之前,必须先有流对象

package com.pb.io.demo2;

/**
创建缓冲区之间必须,先创建流
使用缓冲区,要flush,刷新
*/
/**
创建缓冲区之间必须,先创建流
使用缓冲区,要flush,刷新
*/
import java.io.*;
class BufferedReaderAndWriterDemo1
{
public static void main(String[] args)
{
File source=new File("d:\\demo.txt");
File objFile=new File("d:\\a.txt");
useBuffered(source,objFile);
}
public static void useBuffered(File source,File objFile){ BufferedReader br=null;
BufferedWriter bw=null; try{
//声明缓冲区对象,并将字符流做为参数传入
br=new BufferedReader(new FileReader(source));
bw=new BufferedWriter(new FileWriter(objFile));
//接收读取的长度
String line=null; //读取内容并放入buf中,判断是不是最后
while((line=br.readLine())!=null){
//写入,有多长写多长
bw.write(line,0,line.length());
bw.newLine(); }
System.out.println("读写完成!");
}catch(IOException e){
System.out.println(e.toString()); }finally{
try{
if(bw!=null)
bw.flush();
bw.close();
}catch(IOException e){
System.out.println(e.toString());
}
try{
if(br!=null)
br.close(); }catch(IOException e){
System.out.println(e.toString());
} }
}
}

二、MyBuffered

2.1、示例

package com.pb.io.demo2;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException; public class MyBuffered { private FileReader fr; public MyBuffered(FileReader fr) {
this.fr = fr;
} /*
* 可以一次读一行的方法
*/
public String myReadLine() throws IOException {
// 定义一个临时 容器,原BufferedReader封装的是字符数组
// 为了方便,定义一个StringBuilder
StringBuilder sb = new StringBuilder();
int ch = 0; while ((ch = fr.read()) != -1) {
if (ch == '\r') {
continue;
}
if (ch == '\n') {
return sb.toString();
}
// 读一个存一个
sb.append((char)ch);
}
if(sb.length()!=0){
return sb.toString();
}
return null;
}
public void myClose() throws IOException{
if (fr != null)
fr.close();
}
public static void main(String[] args) throws IOException { File file=new File("d:\\demo.txt");
MyBuffered mb=new MyBuffered(new FileReader(file));
String line=null;
while((line=mb.myReadLine())!=null){
System.out.println(line);
}
mb.myClose();
}
}

三、装饰设计模式

3.1、装饰设计模式

装饰设计模式:

当想要对已经有的对象进行功能增强时,

可以定义类,将已经对象传入,基于已经有的功能,并提供加强功能。

那么自定义的该类就称为装饰类

package com.pb.io.demo3;

class Person{
public void eat(){
System.out.println("吃饭");
}
}
class SuperPerson{
private Person p; public SuperPerson(Person p) {
super();
this.p = p;
} public void superEat(){
System.out.println("开胃酒");
p.eat();
System.out.println("甜点");
System.out.println("来一根");
}
} public class PersonTest { public static void main(String[] args) {
Person p=new Person();
p.eat();
SuperPerson sp=new SuperPerson(p);
sp.superEat(); } }

3.2、与继承之间的关系

装饰类通常会通过构造方法接收被被装饰的对象,并基于被装饰的对象的功能,提供更强的功能

装饰模式比继承灵活,避免了继承体系臃肿

而且降低了类于类之间的关系

装饰类因为增强已有对象,具备的功能和已经的是相同的,只不过提供了更强的功能。

所以装饰类和被装饰类通常是都属于一个体系中。

四、LineNumberReader

4.1、

构造方法摘要
LineNumberReader(Reader in)
使用默认输入缓冲区的大小创建新的行编号 reader。
LineNumberReader(Reader in,
int sz)

创建新的行编号
reader,将字符读入给定大小的缓冲区。


方法摘要
int getLineNumber()

获得当前行号。
void mark(int readAheadLimit)

标记该流中的当前位置。
int read()

读取单个字符。
int read(char[] cbuf,
int off, int len)

将字符读入数组中的某一部分。
String readLine()

读取文本行。
void reset()

将该流重新设置为最新的标记。
void setLineNumber(int lineNumber)

设置当前行号。
long skip(long n)

跳过字符。


4.2、示例

package com.pb.io.demo4;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader; public class LineNumberReaderDemo { public static void main(String[] args) {
LineNumberReader lnr=null;
try {
lnr=new LineNumberReader(new FileReader("d:\\demo.txt"));
//设置开始行叼
lnr.setLineNumber(100);
String line=null;
while((line=lnr.readLine())!=null){
//getLineNumber默认从1开始,设置后从设置的行号开始
System.out.println(lnr.getLineNumber()+":"+line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(lnr!=null)
lnr.close();
} catch (IOException e) {
e.printStackTrace();
}
} } }

4.3、自定义

package com.pb.io.demo4;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader; public class MyLineNumberReader { private Reader reader;
private int lineNumber; public MyLineNumberReader(Reader reader) {
this.reader = reader;
} /*
* 读一行
*/
public String myReadLine() throws IOException {
lineNumber++;
StringBuilder sb = new StringBuilder();
int ch=0;
while ((ch = reader.read()) != -1) {
if (ch == '\r')
continue;
if (ch == '\n')
return sb.toString();
sb.append((char) ch);
}
if (sb.length() != 0)
return sb.toString();
return null; } public void myClose() throws IOException{
reader.close();
} public Reader getReader() {
return reader;
} public void setReader(Reader reader) {
this.reader = reader;
} public int getLineNumber() {
return lineNumber;
} public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
} public static void main(String[] args) throws IOException {
File file=new File("d:\\demo.txt");
MyLineNumberReader mln=new MyLineNumberReader(new FileReader(file));
String line=null;
//mln.setLineNumber(100);
while((line=mln.myReadLine())!=null){
System.out.println(mln.getLineNumber()+":"+line);
}
mln.myClose();
} }

五、字节流

5.1、字节流

OutputStream写、InputStream读

FileOutputStream、FileInputStream 字节流输出、输入流

构造方法摘要
OutputStream()


方法摘要
void close()

关闭此输出流并释放与此流有关的所有系统资源。
void flush()

刷新此输出流并强制写出所有缓冲的输出字节。
void write(byte[] b)

b.length 个字节从指定的 byte 数组写入此输出流。
void write(byte[] b,
int off, int len)

将指定 byte 数组中从偏移量 off 开始的
len 个字节写入此输出流。
abstract
void
write(int b)

将指定的字节写入此输出流。


构造方法摘要
InputStream()


方法摘要
int available()

返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
void close()

关闭此输入流并释放与该流关联的所有系统资源。
void mark(int readlimit)

在此输入流中标记当前的位置。
boolean markSupported()

测试此输入流是否支持 markreset 方法。
abstract
int
read()

从输入流中读取数据的下一个字节。
int read(byte[] b)

从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int read(byte[] b,
int off, int len)

将输入流中最多 len 个数据字节读入 byte
数组。
void reset()

将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。
long skip(long n)

跳过和丢弃此输入流中数据的 n 个字节。


5.2、FileInputStream与FileOutputStream

package com.pb.io.demo5;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; /**
* 使用字节流复制文件
*
*/
public class FileOutputAndFileInputStreamDemo { public static void main(String[] args) {
File source=new File("d:\\1.jpg");
File objFile=new File("d:\\4.jpg");
InputAndOutput2(source,objFile);
}
public static void InputAndOutput(File source,File objFile){
//声明字节流输入,输出对象
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream(source);
fos=new FileOutputStream(objFile);
//声明缓冲区
byte [] buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1){
fos.write(buf, 0, len);
}
System.out.println("=======读写完成========");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis!=null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
/*
* 不建议使用
*/
public static void InputAndOutput2(File source,File objFile){
//声明字节流输入,输出对象
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream(source);
fos=new FileOutputStream(objFile);
//声明大小刚刚缓冲区
byte [] buf=new byte[fis.available()]; //不建议使用available fis.read(buf);
fos.write(buf,0,buf.length); System.out.println("=======读写完成========");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis!=null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
}

六、字节流缓冲区

6.1、示例复制.mp3

package com.pb.io.demo5;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; public class BufferedStreamDemo { public static void main(String[] args) {
File file1=new File("d:\\gm.mp3");
File file2=new File("d:\\mg.mp3");
copy1(file1,file2);
}
public static void copy1(File file1,File file2){
//声明字节流缓冲区对象
BufferedOutputStream bos=null;
BufferedInputStream bis=null;
try {
bis=new BufferedInputStream(new FileInputStream(file1));
bos=new BufferedOutputStream(new FileOutputStream(file2)); //声明缓冲区大小
int by=0;
while((by=bis.read())!=-1){
bos.write(by);
} } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bos!=null)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(bis!=null)
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
} } }

6.2、自定义

package com.pb.io.demo5;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; public class MyBufferedStream { private InputStream is;
private byte[] buf = new byte[1024]; private int pos = 0;
private int count = 0; public MyBufferedStream(InputStream is) {
this.is = is;
} /*
* 一次读一个字节,从缓冲区的(字节数组)获取
*/
public int myRead() throws IOException {
// 通过in对象读取硬盘上的数据,并存在buf中
if (count == 0) {
count = is.read(buf);
if (count < 0) {
return -1;
}
pos = 0;
byte b = buf[pos];
count--;
pos++;
return b & 0xff;
} else if (count > 0) {
byte b = buf[pos];
count--;
pos++;
return b & 0xff;
}
return -1; } public void myClose() throws IOException {
is.close();
} public static void main(String[] args) {
File file1 = new File("d:\\gm.mp3");
File file2 = new File("d:\\kk.mp3");
copy1(file1, file2);
} public static void copy1(File file1, File file2) {
// 声明字节流缓冲区对象
BufferedOutputStream bos = null;
MyBufferedStream mbs = null;
try {
mbs = new MyBufferedStream(new FileInputStream(file1));
bos = new BufferedOutputStream(new FileOutputStream(file2)); // 声明缓冲区大小
int by = 0;
while ((by = mbs.myRead()) != -1) {
bos.write(by);
} } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bos != null)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
mbs.myClose();
} catch (IOException e) {
e.printStackTrace();
}
} } }

七、转换

7.1、字节流转换字符流

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

Writer out
= new BufferedWriter(new OutputStreamWriter(System.out));

7.2、示例

接收键盘输入,使用转换流实现

package com.pb.io.demo6;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* 接收键盘输入,并将内容写入文件
*
*/
public class Demo { public static void main(String[] args) { BufferedReader br=null;
BufferedWriter bw=null; try {
//声明输入流,使用转换流实现
br=new BufferedReader(new InputStreamReader(System.in)); //声明输出流,使用转换流实现
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:\\t.txt"))); //接收键盘录入
String str=null;
System.out.println("请输入要写入文件的内容,输入over结束!");
//输入over结束
while(!(str=br.readLine()).equals("over")){
bw.write(str);
bw.newLine();
} } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bw!=null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
} try {
if(br!=null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
} } }

八、流操作的规律

1、明确源和目的

  源:输入流。InputStream,Reader

  目的:输出流 .OutputStream,Writer

2、操作的数据是否为纯文本

  是:字符流。Reader、Writer

  不是:字节流。InputStream、OutputStream

3、当体系明确后,在明确要使用哪个具体对象。

  通过设备来进行区别。

  源设备:内存、硬盘、键盘

  目的设备:内存、硬盘、控制台

九、重定向IO

9.1、示例

//设置输入流的
System.setIn(new FileInputStream("d:\\demo.txt"));
//设置的输出流的方向
System.setOut(new PrintStream("d:\\zz.txt"));

十、系统信息

10.1、示例

package com.pb.io.demo6;

import java.util.Properties;

public class Demo1 {

    public static void main(String[] args) {
Properties prop=System.getProperties();
prop.list(System.out); //可以设置为输出流对象new PrintWriter(文件)
} }
-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Java\jre1.8.0_60\bin
java.vm.version=25.60-b23
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.script=
user.country=CN
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=
java.vm.specification.name=Java Virtual Machine Specification
user.dir=F:\work\IODemo
java.runtime.version=1.8.0_60-b27
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Java\jre1.8.0_60\lib\endorsed
os.arch=amd64
java.io.tmpdir=C:\Users\ADMINI~1\AppData\Local\Temp\
line.separator= java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 7
sun.jnu.encoding=GBK
java.library.path=C:\Java\jre1.8.0_60\bin;C:\Windows\Su...
java.specification.name=Java Platform API Specification
java.class.version=52.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
os.version=6.1
user.home=C:\Users\Administrator
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=UTF-8
java.specification.version=1.8
user.name=Administrator
java.class.path=F:\work\IODemo\bin
java.vm.specification.version=1.8
sun.arch.data.model=64
java.home=C:\Java\jre1.8.0_60
sun.java.command=com.pb.io.demo6.Demo1
java.specification.vendor=Oracle Corporation
user.language=zh
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.8.0_60
java.ext.dirs=C:\Java\jre1.8.0_60\lib\ext;C:\Window...
sun.boot.class.path=C:\Java\jre1.8.0_60\lib\resources.jar...
java.vendor=Oracle Corporation
file.separator=\
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=amd64

JAVA基础学习day20--IO流二-缓冲流、字节流的更多相关文章

  1. 【java基础学习】IO流

    IO流 字节流InputStream和OutputStream 字符流Writer和Reader 装饰模式

  2. java基础学习总结——GUI编程(二)

    一.事件监听

  3. java基础学习总结——GUI编程(二) 未学习

    一.事件监听

  4. JAVA基础学习之路(二)方法定义,重载,递归

    一,方法的定义: package test; public class test1 { public static void main(String args[]) { int result = ad ...

  5. 转载-java基础学习汇总

    共2页: 1 2 下一页  Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3     Java基础学习总结——Java对象的序列化和 ...

  6. java基础(24):转换流、缓冲流

    1. 转换流 在学习字符流(FileReader.FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputS ...

  7. java的 IO流之缓冲流(转载)

    java缓冲流本身不具IO功能,只是在别的流上加上缓冲提高效率,像是为别的流装上一种包装.当对文件或其他目标频繁读写或操作效率低,效能差.这时使用缓冲流能够更高效的读写信息.因为缓冲流先将数据缓存起来 ...

  8. java:IO流(处理流(缓冲流,转换流,数据流),对象的序列化,Properties)

    字节缓冲流:(BufferedInputStream,BufferedOutStream) *按照流的功能来分:节点流和处理流 *节点流可以直接操作数据源: *InputStream *--FileI ...

  9. java - >IO流_缓冲流(高效流)

    缓冲流(高效流) 在我们学习字节流与字符流的时候,大家都进行过读取文件中数据的操作,读取数据量大的文件时,读取的速度会很慢,很影响我们程序的效率,那么,我想提高速度,怎么办? Java中提高了一套缓冲 ...

随机推荐

  1. Oracle 给已创建的表增加自增长列

    对于已经创建的表,在特殊需求下,需要增加一个自增长列步骤: --1. 增加 自增长列 ); --2. 程序方式更新设置 IdNum 列 值 --3.查询最大 ) From Limsbusinessen ...

  2. iOS-高德地图-手动环境搭建

    一. 下载地图包 1. 链接地址: http://lbs.amap.com/api/ios-sdk/download/ 2.需要下载的包,并导入包 (1) MAMapKit-5.framework   ...

  3. js 实现各种排序

    一 冒泡排序 一万个随机数排序五次执行时间分别为 362 389 361 372 408 毫秒 var arr=[]; for(var j=0;j<10000;j++){ arr.push(Ma ...

  4. [python]pip常用命令(转载)

    用阿里云服务器,使用pip安装第三方库的时候卡的要死.所以我就想pip能不能安装本地的包. 找到了这篇博客: http://me.iblogc.com/2015/01/01/pip%E5%B8%B8% ...

  5. 手把手教你从购买vps到搭建一个node服务器

    要准备什么? 1.5刀 2.最好有FQ软件(可以用蓝灯) let's Go! 一.vps购买 vps可以选择digital ocean(do) 链接 ,由于是外国网站,响应比较慢,所以最好翻个墙. g ...

  6. Android 学习笔记之Volley开源框架解析(四)

    学习内容: 1.NetWorkDispatcher网络请求线程调度... 2.NetWork网络请求抽象类... 3.BasicNetWork网络请求抽象类的具体实现... 4.NetWorkResp ...

  7. 价值100W的经验分享: 基于JSPatch的iOS应用线上Bug的即时修复方案,附源码.

    限于iOS AppStore的审核机制,一些新的功能的添加或者bug的修复,想做些节日专属的活动等,几乎都是不太可能的.从已有的经验来看,也是有了一些比较常用的解决方案.本文先是会简单说明对比大部分方 ...

  8. mysql 线上not in查询中的一个坑

    今天早上开发又过来说,怎么有个语句一直没有查询出结果,数据是有的呀,并发来了如下的sql(为了方法说明,表名及查询均做了修改): select * from t2 where t2.course no ...

  9. Mysql大量插入随机数据方法--存储过程

    创建测试表: mysql)); 创建存储过程: mysql> delimiter // mysql> create procedure rand_data(in num int) -> ...

  10. 字符串与json之间的相互转化

    先在数据库中建表: 再从后台将表取出来,然后转化为json格式,再将其执行ToString()操作后,赋值给前台的隐藏域. 注意引用using Newtonsoft.Json; 前台利用js将隐藏域中 ...