1.IO stream
1.1 概述
-
IO流的简述
IO流可以代表dist file ,deviece ,network(socket)等对象,我们操作IO流就相当操作这些对象
IO流支持各种primitive date type ,string 和oject数据类型
-
关系
byte stream class 都是继承
InputStream
,OutputStream
类,其中byte steam class 有FileInputStream
FileOutputStream
,其他IO流都是从该类中继承发展出来的
1.2 byte stream
-
简述
使用
FileInputStream
FileOutputSteam
来进行输入和输出,这些类每次都只操作一个字节 -
例子
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyBytes { public static void main(String[] args) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("xanadu.txt"); out = new FileOutputStream("outagain.txt"); int c; while ((c = in.read()) != -1) { out.write(c); } } finally { //注意,不管有没有读取和输出成功,都要关闭流 if (in != null) { in.close(); } if (out != null) { out.close(); } } } }
-
使用环境
一般都不会直接使用byte streams,因为其实相当于最原生的io stream class,我们可以使用在该类基础山发展出来的更高级封装的io stream,来操作复杂的数据类型,例如如果读取的文件中包含charater字符,则是更好使用charater stream
1.3 character stream
-
简述
FileReader
FileWriter
每次读取一个字符(charater) -
例子
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class CopyCharacters { public static void main(String[] args) throws IOException { FileReader inputStream = null; FileWriter outputStream = null; try { inputStream = new FileReader("xanadu.txt"); outputStream = new FileWriter("characteroutput.txt"); int c; while ((c = inputStream.read()) != -1) { outputStream.write(c); } } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } } }
这个是一个一个字符的读取
-
一行一行的读取
即就是已carriage-return("/r"),single line-feed("/n")为lien terminator
import java.io.FileReader; import java.io.FileWriter; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.IOException; public class CopyLines { public static void main(String[] args) throws IOException { BufferedReader inputStream = null; PrintWriter outputStream = null; try { inputStream = new BufferedReader(new FileReader("xanadu.txt")); outputStream = new PrintWriter(new FileWriter("characteroutput.txt")); String l; while ((l = inputStream.readLine()) != null) { outputStream.println(l); } } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } } }
-
使用环境
文件是纯文本,则可以使用该流来读取出来,在程序中就可以获得一个一个字符
1.4 buffered stream
-
简述
BufferedReader
BufferedWriter
,缓存流就是在读取的时候,先读取到缓存中,这样之后的读取就可以直接从缓存中读取,这样速度快并且减少操作硬盘的资源的消耗 -
例子
inputStream = new BufferedReader(new FileReader("xanadu.txt")); outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));
说明:如果你想在提前把数据写入硬盘,可以调用
flush
方法来把数据写入到操作的对象中(例如,硬盘)所有的io streams class都有flush方法,但只有buffered stream 的flush 才其作用
还有一些输出流支持自动flush,例如 an autoflush
PrintWriter
object flushes the buffer on every invocation ofprintln
orformat
-
使用环境
建议都使用
1.5 data stream
-
简述:所有的data streams 都是继承该
DataOutput
DataInput
例如DataInputSteam
DataOutputSteam
data streams 支持所有primitive type 和string 的二进制流
-
例子
static final String dataFile = "invoicedata"; static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 }; static final int[] units = { 12, 8, 13, 29, 50 }; static final String[] descs = { "Java T-shirt", "Java Mug", "Duke Juggling Dolls", "Java Pin", "Java Key Chain" }; out = new DataOutputStream(new BufferedOutputStream( new FileOutputStream(dataFile))); for (int i = 0; i < prices.length; i ++) { out.writeDouble(prices[i]); out.writeInt(units[i]); out.writeUTF(descs[i]); } in = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile))); double price; int unit; String desc; double total = 0.0; try { while (true) { price = in.readDouble(); unit = in.readInt(); desc = in.readUTF(); System.out.format("You ordered %d" + " units of %s at $%.2f%n", unit, desc, price); total += unit * price; } } catch (EOFException e) { }
说明:
Notice that
DataStreams
detects an end-of-file condition by catchingEOFException
已什么方式输入,到时就应该使用相应的方式读出
-
使用环境
如果涉及到记录的存储,即该一条数据中有多个数据类型,int string,double等则可以使用该流
data streams 中的double 类型不能很好的描述currency value,即double 不能格式话输入(即输入不了0.1中这样的数值),所以应该使用
java.math.BigDecimal
来表示金额,其实对象,应该使用object steams
1.6 object stream
-
简述:
object steams支持objcet ,primitive tyep ,和string的二进制流
所有的object steams class都是从接口
objectInput
Object0utput
继承的,例如ObjectInputSteam
objectInputStream
objectInput
Object0utput
是DataInput
DataOutput
的子接口,所以Object stream不但支持object类型,也支持primitive tyep ,和string -
例子:
Object ob = new Object(); out.writeObject(ob); Object ob2 = in.readObject();
-
使用环境
其实object stream 是在data stream之上进行扩展的,如果一条记录中的数据,基本数据类型和string都记录,则使用data stream,如果涉及到 currency value(金额,使用
BigDecimal
),或者calendar(date),则需要使用object stream进行记录
1.7 standar stream
1.8 scanning 和Formatting
-
scanning
-
简述:
Scanner
类支持我们自定义terminator来分割读取的文本,其中默认是white space(blanks, tabs, and line terminators.)Scanner
类支持translating individual tokens,不懂得地方,就是在转化得时候,会设计到locale(地区的设置)
-
-
特点
- 使用Scanner类,可以从二进制流中读出token(使用delimiter来划分,默认是whitespace),token可以是string,int,double等
- 使用Scanner可以处理String字符串
- Scanner可以接收正则表达式,找出匹配正则表达式的token(这个可以用来查找以及统计某个字符串的个数)
-
例子
import java.io.FileReader; import java.io.BufferedReader; import java.io.IOException; import java.util.Scanner; import java.util.Locale; public class ScanSum { public static void main(String[] args) throws IOException { Scanner s = null; double sum = 0; try { s = new Scanner(new BufferedReader(new FileReader("usnumbers.txt"))); s.useLocale(Locale.US); while (s.hasNext()) { if (s.hasNextDouble()) { sum += s.nextDouble(); } else { s.next(); } } } finally { s.close(); } System.out.println(sum); } }
And here’s the sample input file,
usnumbers.txt
8.5 32,767 3.14159 1,000,000.1
-
使用环境
1.9总结
data stream 是原始的io流,其每次操作一个字节,其他stream 都是在其基础上发展起来的,例如charater stream使用于操作纯文本的文件,同时可以结合scanner来进行分割读取,而datastream则是适合存储记录,这个记录中的数据类型有primitive type和string,但记录中涉及到金额和时间,则需要使用object stream,使用上面的stream 进行读取操作的时候,最好使用buffered stream来进行缓存,这样提高读取的性能
2.资料链接
-
scanner
https://www.baeldung.com/java-scanner
共有条评论 网友评论