首页 > 代码库 > Java IO 流
Java IO 流
<style>html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { margin: 0; padding: 0; border: 0 } body { font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px; line-height: 1.6; color: #333; background-color: #fff; padding: 20px; max-width: 960px; margin: 0 auto } body>*:first-child { margin-top: 0 !important } body>*:last-child { margin-bottom: 0 !important } p,blockquote,ul,ol,dl,table,pre { margin: 15px 0 } h1,h2,h3,h4,h5,h6 { margin: 20px 0 10px; padding: 0; font-weight: bold } h1 tt,h1 code,h2 tt,h2 code,h3 tt,h3 code,h4 tt,h4 code,h5 tt,h5 code,h6 tt,h6 code { font-size: inherit } h1 { font-size: 28px; color: #000 } h2 { font-size: 24px; border-bottom: 1px solid #ccc; color: #000 } h3 { font-size: 18px } h4 { font-size: 16px } h5 { font-size: 14px } h6 { color: #777; font-size: 14px } body>h2:first-child,body>h1:first-child,body>h1:first-child+h2,body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child { margin-top: 0; padding-top: 0 } a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6 { margin-top: 0; padding-top: 0 } h1+p,h2+p,h3+p,h4+p,h5+p,h6+p { margin-top: 10px } a { color: #4183C4; text-decoration: none } a:hover { text-decoration: underline } ul,ol { padding-left: 30px } ul li>:first-child,ol li>:first-child,ul li ul:first-of-type,ol li ol:first-of-type,ul li ol:first-of-type,ol li ul:first-of-type { margin-top: 0px } ul ul,ul ol,ol ol,ol ul { margin-bottom: 0 } dl { padding: 0 } dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px } dl dt:first-child { padding: 0 } dl dt>:first-child { margin-top: 0px } dl dt>:last-child { margin-bottom: 0px } dl dd { margin: 0 0 15px; padding: 0 15px } dl dd>:first-child { margin-top: 0px } dl dd>:last-child { margin-bottom: 0px } pre,code,tt { font-size: 12px; font-family: Consolas, "Liberation Mono", Courier, monospace } code,tt { margin: 0 0px; padding: 0px 0px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8 } pre>code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent } pre { background-color: #f8f8f8; border: 1px solid #ccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px } pre code,pre tt { background-color: transparent; border: none } kbd { background-color: #DDDDDD; background-image: linear-gradient(#F1F1F1, #DDDDDD); background-repeat: repeat-x; border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD; border-style: solid; border-width: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 10px; padding: 1px 4px } blockquote { border-left: 4px solid #DDD; padding: 0 15px; color: #777 } blockquote>:first-child { margin-top: 0px } blockquote>:last-child { margin-bottom: 0px } hr { clear: both; margin: 15px 0; height: 0px; overflow: hidden; border: none; background: transparent; border-bottom: 4px solid #ddd; padding: 0 } table th { font-weight: bold } table th,table td { border: 1px solid #ccc; padding: 6px 13px } table tr { border-top: 1px solid #ccc; background-color: #fff } table tr:nth-child(2n) { background-color: #f8f8f8 } img { max-width: 100% }</style>
关于面向对象的方法的一个说明。 对于多态而言,可以使用子类来实例化父类,这对于面向对象有很重要的作用,但是,子类中的一些独有的方法父类就掉用不到了,这个时候可以使用向下转型,将父类进行强行的数据转型,就可以使用这些方法了
字节流和字符流
字节流InputStream/OutputStream ,只能操作byte
字符流Reader/Writer
FileoutputStream(File f)
字节流本身是只能操作byte的。
对于这一个类,如果文件不存在会自动创建
write()方法默认会将文件进行覆盖
可以使用构造方法FileoutputStream(File f,boolean append),这样就可以指定要不要使用追加模式
FileoutputStream(File f)
方法 - available() 获得可以读取的字节数
字符流
一般一个字符为两个字节,可以直接操作字符串
会用到缓冲区
FileWriter/FileReader
默认依然是覆盖,要追加只要和FileoutputStream类似加boolean标志就好了
Filereader读取到char/char[]
字节流和字符流的不同
字节流是直接与文件操作,不会用到缓冲区 字符流数据先放在缓冲区,然后再从缓冲区写到文件,要记得fiush()或者close()
字节-字符的转换流
- InputStreamReader
将一个输入字节流转为字符流,是Reader的子类 - OutputStreamWriter
将一个输出字节流转为字符流,是Writer的子类
FileWriter是OutputStreamWriter的子类 FileReader是OutputStreamReader的子类
内存操作流
ByteArrayInputStream(byte[])
将byte中是数据写入内存中
ByteArrayOutputStream()
实际的意思就是说,通过输入流将数据写入到内存里面,然后通过输出流把内存里面的东西取出来!
private static void tesByteArrayInputStream() {
// 创建ByteArrayInputStream字节流,内容是ArrayLetters数组
ByteArrayInputStream bais = new ByteArrayInputStream(ArrayLetters);
// 从字节流中读取5个字节
for (int i=0; i<LEN; i++) {
// 若能继续读取下一个字节,则读取下一个字节
if (bais.available() >= 0) {
// 读取“字节流的下一个字节”
int tmp = bais.read();
System.out.printf("%d : 0x%s\n", i, Integer.toHexString(tmp));
}
}
// 若“该字节流”不支持标记功能,则直接退出
if (!bais.markSupported()) {
System.out.println("make not supported!");
return ;
}
// 标记“字节流中下一个被读取的位置”。即--标记“0x66”,因为因为前面已经读取了5个字节,所以下一个被读取的位置是第6个字节”
// (01), ByteArrayInputStream类的mark(0)函数中的“参数0”是没有实际意义的。
// (02), mark()与reset()是配套的,reset()会将“字节流中下一个被读取的位置”重置为“mark()中所保存的位置”
bais.mark(0);
// 跳过5个字节。跳过5个字节后,字节流中下一个被读取的值应该是“0x6B”。
bais.skip(5);
// 从字节流中读取5个数据。即读取“0x6B, 0x6C, 0x6D, 0x6E, 0x6F”
byte[] buf = new byte[LEN];
bais.read(buf, 0, LEN);
// 将buf转换为String字符串。“0x6B, 0x6C, 0x6D, 0x6E, 0x6F”对应字符是“klmno”
String str1 = new String(buf);
System.out.printf("str1=%s\n", str1);
// 重置“字节流”:即,将“字节流中下一个被读取的位置”重置到“mark()所标记的位置”,即0x66。
bais.reset();
// 从“重置后的字节流”中读取5个字节到buf中。即读取“0x66, 0x67, 0x68, 0x69, 0x6A”
bais.read(buf, 0, LEN);
// 将buf转换为String字符串。“0x66, 0x67, 0x68, 0x69, 0x6A”对应字符是“fghij”
String str2 = new String(buf);
System.out.printf("str2=%s\n", str2);
}
}
管道流
管道流就是实现两个进程之间的通信
PipeOutputStream PipeInputStream 使用的时候要使用connect()把输入输出流连接起来,Connect是PipeOutputStream的方法,用来连接一个PipeInputStream
打印流
PrintStream
定义了很多的print和pringtln方法,可以打印任意数据类型
System.out就是定位在输出设备的PrintStream
构造方法,指定输出的位置
PrintSTream(OutputStream out)
这样打印输出更加方便了,PrintStream就是OutputStream的子类,可以方便的进行输出,这样的设计称之为装饰设计模式
PrintWriter与上面的类似
格式化输出
类似于C语言的格式化输出 %d,%s,%f,%c
ps.printf("姓名%s,年龄:%d",a,b);
System.in以及BufferedReader(字符流)
是一个InputStream
BufferedReader buf=null;
buf=new BufferedReader(new InputStreamReader(System.in));
String str=null;
try {
while ((str=buf.readLine())!=null){
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
输入输出重定向
System.setOut(new PrintStream(new FileOutputStream("D:/a.txt")));
实际上in、out、err就是System的三个常量,可以通过set方法改变,然后就完成了重定向的作用。
Scanner
在java.util包中,可以实现BufferedReader的全部功能,是一个工具类
- 默认的分隔符是空格,可以自行设置
- 非常强大,可以接受多种类型的数据,但是对于日期类型没有支持,可以使用Scanner.hasNext(Pattern)/next(Pattern)匹配来取出数据
-
可以接受File,做一系列文件操作
Scanner scanner=new Scanner(System.in); scanner.useDelimiter("\n");//修改分割符 int a=0; float f=0f; String date=null; if(scanner.hasNextInt()){ a=scanner.nextInt(); } if(scanner.hasNextFloat()){ f=scanner.nextFloat(); } if(scanner.hasNext("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")){ date=scanner.next("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"); } System.out.println(a+" "+f+" "+date); try { Date date1=new SimpleDateFormat("yy-MM-dd hh:mm:ss").parse(date); System.out.println(date1); } catch (ParseException e) { e.printStackTrace(); }
合并流
压缩流
支持三种格式的压缩,zip/jar/Gzip,这里以zip为例另外两种都是一样的
ZipEntry,就是压缩文件目录下的每一个文件
-
ZipOutputStream(OutputStream)
- PutNextEntry(ZipEntry ?)
可以将文件、文件夹进行压缩
ZipFile类
专门表示压缩文件的类
回退流
字符编码
获得本机编码
System.getProperity("file.encoding")
常见的编码格式
- iso8859-1单字节编码,只能表示英文
- GBK国标,表示汉字
- unicode 16进制两个字节的编码,最标准的,但是不兼容iso-8859-1
- utf 变长的编码,一个字符长度1--6不等,可以表示所有语言的字符、
关于io流的结构
输入流
- InputStream
- ByteArrayInputStream(byte[])
- FileInputStream(File)
- PipedInputStream
- SequenceInputStream(InputStream,InputStream)
- FilterInputStream
- BufferedInputStream(InputStream)
- PushbackInputStream
- DataInputStream
- ObjectInputStream
输出流
- OutputStream
- ByteArrayOutputStream
- FileOutputStream
- PipedOutputStream
- FilterOutputStream
- BufferedOutputStream
- PrintWriter
- DataOutputStream
- ObjectOutputStream
常见的方法
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提供了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( ) : 关闭输出流并释放与流相关的系统资源。
java的流类提供了结构化方法,如,底层流和高层过滤流。
而高层流不是从输入设备读取,而是从其他流读取。同样高层输出流也不是写入输出设备,而是写入其他流。
使用"分层对象(layered objects)",为单个对象动态地,透明地添加功能的做法,被称为Decorator
Pattern。Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得
decorator的用法变得非常的透明--无论对象是否被decorate过,传给它的消息总是相同的。这也是Java I/O
类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类
- DataInputStream 包含了一整套读取primitive数据的接口
- BufferedInputStream,为InputStream增加了一个缓冲区,缓冲区的大小是8k
- PushbackInputStream 有一个"弹压单字节"的缓冲区,可以把最后读到的那个字节再压回去
- DataOutputStream 包括写入primitive数据的全套接口。
- PrintStream(inpurstream,boolean autoflush) 打印流
- BufferedOutputStream 有缓冲区
Java IO 流