Java---IO加强(2)
转换流
★转换流功能1:充当字节流与字符流之间的桥梁
需求:模拟英文聊天程序,要求:
(1) 从键盘录入英文字符,每录一行就把它转成大写输出到控制台;
(2) 保存聊天记录到字节流文件。
要求1的设计分析:
1)需要从键盘接收录入,得用System.in,它是字节输入流InputStream;
2)需要处理字符,可以自己把字节强转成字符,也可以用字符流;
3)需要类似readLine的功能,而这个方法在字符流BufferedReader中有(而且该类有缓冲增速)。
综上,采用转换流把字节流转成字符流处理比较合理,即使用InputStreamReader
要求2的设计分析:
1)需要把字符数据按行保存到字节流文件 ;
2)字符流采用BufferedWriter比较合适,因为它有newLine方法且能实现高效;
3)字节流文件,得采用FileOutputStream。
综上,采用转换流把字符流转成字节流处理比较合理,即使用OutputStreamWriter
代码实现:
package io.transfer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class TranStreamDemo {
public static void main(String[] args) throws IOException {
//输入
InputStream in = System.in;
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
//输出
OutputStream out = new FileOutputStream("chat.txt");
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bw = new BufferedWriter(osw);
String line = null;
while( (line=br.readLine())!=null){
if("over".equals(line)){
//养成好的代码习惯:调用String中的方法时,把常量字符串放在前面,防止变量为null而导致异常
break;
}
System.out.println( line.toUpperCase() );
bw.write(line);
bw.newLine();
bw.flush();//字符流是带缓冲的,必须刷缓冲
}
}
}
转换流
(InputStreamReader和OutputStreamWriter)
★转换流功能2:字符编码转换
采用FileWriter以默认方式编码
FileOutputStream+默认编码表
采用转换流以默认方式编码
OutputStreamWriter + FileOutputStream + 默认编码表
采用转换流以指定编码方式编码
OutputStreamWriter + FileOutputStream +指定编码表
采用转换流以指定编码方式解码
InputStreamReader + FileInputStream +指定编码表
代码实现:
package io.transfer;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TranStreamDemo2 {
public static void main(String[] args) {
try {
//readTextDecoding1();
//readTextDecoding2();
writeTextEncoding();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void writeTextEncoding() throws IOException {
//第一种: FileWriter+默认编码表
FileWriter fw = new FileWriter("files\\w_utf-8.txt");//该文件的编码由平台(如MyEclipse或dos窗口)定,不一定是utf-8
fw.write("每天进步一点点...");
fw.close();
//第二种: OutputStreamWriter+默认编码表
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("files\\w_utf-8_2.txt"));//该文件的编码由平台(如MyEclipse或dos窗口)定,不一定是utf-8
osw.write("第天进步一点点...");//牛耳
osw.close();
//第三种: OutputStreamWriter+指定编码表
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("files\\w_utf-8_3.txt"),"utf-8");//该文件的编码一定是utf-8,因为是我们自己指定的
osw2.write("第天进步一点点...");
osw2.close();
}
private static void readTextDecoding1() throws IOException {
FileReader fr = new FileReader("files\\utf-8.txt");//采用默认编码表解码
char[] cbuf = new char[10];
int len=0;
while( (len=fr.read(cbuf))!=-1){
String str = new String(cbuf,0,len);
System.out.print(str);
}
fr.close();
}
private static void readTextDecoding2() throws IOException {
//InputStreamReader isr = new InputStreamReader(new FileInputStream("files\\gbk.txt"));//如果不指定编码表,则是采用默认的
//用转换流自己指定解码表----只要文件的编码表和这里指定的解码表相同,就不会出现乱码
//InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\gbk.txt"), "gbk"); //ok
//InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\utf-8.txt"), "gbk");//乱码
InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\utf-8.txt"), "utf-8");//ok
char[] cbuf = new char[20];
int len = isr.read(cbuf);
String str = new String(cbuf,0,len);
System.out.println(str);
isr.close();
}
}
打印流
★打印流的特点:
1)只有输出没有输入。PrintStream是字节打印流,PrintWriter是字符打印流。
2)能够方便地打印各种数据“值表示形式”,提供了一系列的打印功能(只有它有,其它流都没有。)
3)和其他输出流不同,它永远不会抛出IOException异常(构造方法除外),异常内部解决且设置了内部标志。
4)可创建具有自动刷新的功能,可使用带换行符的println()方法。
5)(在构造方法中)可以指定字符集编码的。
★关于打印流的自动刷新
autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区。
* —其实是因为这几个方法中帮我们调用了out.flush()。
代码实现:
//演示PrintStream类的自动刷新功能
package io.print;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
/**
*
* @author 陈浩翔
*
* 2016-4-24
*/
//演示PrintStream类的自动刷新功能
public class PrintStreamDemo {
public static void main(String[] args) {
try {
demo1();
demo2();
for(int i=0;i<10;i++){
System.out.println(i);
}
//屏幕终端不会有输出的,因为运行了demo2();
//把System.out的输出目的地从屏幕更改到日志文件了
} catch (IOException e) {
e.printStackTrace();
}
}
//把System.out的输出目的地从屏幕更改到日志文件
private static void demo2() throws IOException {
FileOutputStream font = new FileOutputStream("log.txt");
PrintStream out = new PrintStream(font,true);
System.setOut(out);
}
private static void demo1() throws IOException {
PrintStream out =new PrintStream("print.txt");
//out.write()只写入一个字节(二进制的8位)的信息,如果参数大于一个字节的范围,
//那么实际上只会写入最后一个字节的数据
out.write(97);
out.write(353);
//最后一个字节是97,因此写入的是一个字符'a'----写入的是值的表现形式
System.out.write(353);//输出'a'
System.out.flush();
out.println(345);//把参数转换成字符串输出
//上一句等价于out.write( String.valueOf(i) )
//※总之,PrintStream中用write()输出的是字节数据且每次只输出一个字节,而print()输出的是数据的值的表现形式即转换成字符串输出。
//JSP中的out对象就是这种类型。要输出字节数据如图片声明等二进制格式则必须用write(),而输出页面数据(字符)则要用print()或println()
}
}
//演示PrintWriter类的自动刷新功能
package io.print;
import java.io.IOException;
import java.io.PrintWriter;
/**
*
* @author 陈浩翔
*
* 2016-4-24
*/
//演示PrintWriter类的自动刷新功能
public class PrintStreamDemo2 {
public static void main(String[] args) {
demo1();
try {
demo2();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void demo1() {
//默认不自动刷新的
PrintWriter out =new PrintWriter(System.out);
out.print("Hello World");//不会自动刷新
out.println("Hello World");//不会自动刷新
out.flush();//手动刷新
}
private static void demo2() throws IOException {
//设置自动刷新的
PrintWriter out = new PrintWriter(System.out,true);
out.print("Hello World");//不会自动刷新
out.println("Hello World");//会----因为println()内部调用了out.flush()
out.print("Hello3 \n");//不会
out.print("Hello3 \r\n");//不会
out.printf("%s", "Hello4");//会
/*总之:
* autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区。
* ---其实是因为这几个方法中帮我们调用了out.flush()。
*/
}
}
IO包中的其他流
下面三个都是内存数组:
★字节数组流
ByteArrayInputStream与ByteArrayOutputStream
★字符数组流
CharArrayReader与CharArrayWriter
★字符串流
StringReader 与 StringWriter
1、用于操作字节数组的流对象,其实它们就是对应设备为内存的流对象。
2、该流的关闭是无效的,因为没有调用过系统资源。
3、按照流的读写思想操作数组中元素。
★序列流
SequenceInputStream ——对多个流进行合并
将多个流进行逻辑串联(合并变成一个流,操作起来很方便,因为多个源变成了一个源)
IO流知识点小结
流是用来处理数据的。
处理数据时,一定要先明确数据源与数据目的地(数据汇)。
数据源可以是文件、键盘或者其他流。
数据目的地可以是文件、显示器或者其他流。
流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。
★ IO流体系
使用要点:看顶层(父类共性功能),用底层(子类具体对象)。
命名规律:
每个子类的后缀名都是所属体系的父类的名称,很容易区分所属的体系。
而且每一个子类前缀名都是该子类对象的功能体现。
掌握IO流体系的要点和规律,开发时设计与查找相应的类就容易多了
Java---IO加强(2)的更多相关文章
- java.IO输入输出流:过滤流:buffer流和data流
java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...
- Java:IO流与文件基础
Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...
- Java IO之字符流和文件
前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...
- java Io流向指定文件输入内容
package com.hp.io; import java.io.*; public class BufferedWriterTest{ public static void main(String ...
- java Io文件输入输出流 复制文件
package com.hp.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java ...
- java Io流更新文件内容
package com.hp.io; import java.io.FileOutputStream; import java.io.IOException; public class FileOut ...
- java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- java.io.NotSerializableException: test.io.file.Student
java.io.NotSerializableException: test.io.file.Student at java.io.ObjectOutputStream.writeObject0 ...
- java.io.IOException: mark/reset not supported
java.io.IOException: mark/reset not supported at java.io.InputStream.reset(InputStream.java:348) at ...
- Java IO流学习总结
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
随机推荐
- android应用的不同版本间兼容性处理
在Android系统中向下兼容性比较差,但是一个应用APP经过处理还是可以在各个版本间运行的.向下兼容性不好,不同版本的系统其API版本也不同,自然有些接口也不同,新的平台不能使用旧的API,旧的平台 ...
- poj 1780 code(欧拉路)
/* 对于n为密码想要序列最短 那么 1234 2345 这两个一定挨着 就是说 前一个的后n-1位是后一个的前n-1位 假设n==3 我们用0-99作为点的编号建图 然后每个点连出去10条边 两个相 ...
- 本文实例汇总了C#中@的用法,对C#程序设计来说有不错的借鉴价值。
具体如下: 一 字符串中的用法 1.学过C#的人都知道C# 中字符串常量可以以@ 开头声名,这样的优点是转义序列“不”被处理,按“原样”输出,即我们不需要对转义字符加上 \ (反斜扛),就可以轻松co ...
- Android Service生命周期及用法
Service概念及用途:Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行, ...
- (转)PHP自定义遍历目录下所有文件dir(),readdir()函数
方法一:使用dir()遍历目录 dir()函数,成功时返回Directory类实例 PHP dir() 语法格式为: dir(directory);//directory为需要显示文件名的目录名称,可 ...
- MySQL 选择数据库
MySQL 选择数据库 在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库. 从命令提示窗口中选择MySQL数据库 在 mysql> 提示窗口中可以很简 ...
- javascript基础学习(十三)
javascript之文档对象 学习要点: 文档对象 文档对象的应用 一.文档对象 Document对象是代表一个浏览器窗口或框架中的显示HTML文件的对象.javascript会为每个HTML文档自 ...
- RSA加密算法正确性证明
RSA加密算法是利用大整数分解耗时非常大来保证加密算法不被破译. 密钥的计算过程为:首先选择两个质数p和q,令n=p*q. 令k为n的欧拉函数,k=ϕ(n)=(p−1)(q−1) 选择任意整数a,保证 ...
- Android学习----发行版本
Android 1.1(Bender“发条机器人”) Android 1.5( Cupcake“纸杯蛋糕”) Android 1.6(Donut 甜甜圈) Android 2.0(Éclair:闪电泡 ...
- 百度上传插件WebUploader,angularjs指令封装
1.WebUploader特点 官网地址:http://fex.baidu.com/webuploader/ 1.1 分片.并发 分片与并发结合,将一个大文件分割成多块,并发上传,极大地提高大文件的上 ...