I/O流

管道操作基本步骤【流模型】
1、选择关键: ①在输入流、输出流;【立场都是站在程序,因此输入流时程序一定是目的地;在输出流程序一定是数据源;】 ②、选择管道大小(字节,字符) ③找到另外一个端点【例如:File Input Stream 数据源的文件字 使用字节流管理 输入程序 // File out stream 程序将数据源 通过字节流 输出给文件;】
2、创建管道,new出来; 容易出现异常,因此在new之前先将对象赋值为NUll;
3、操作管道(输入、输出)
4 、关闭管道; 【try-catch-finally { if(对象 != null) {对象.close() ;} }
//输入输出一定都有异常;要try-catch; 在其中的finally一定要进行关闭操作;

【实际操作1】:从控制台输入信息到成为文件;
FileoutputStreamWrite fw = null ; // 写在外面避免try-catch将他变成局部变量;
fw = new FileWriter(“poem.txt” ;+ try-catch;首先写关闭管道
fw.write(str);
finally{
if( fw != null ){
fw.close(); 对他try-catch;IO异常;
}
}


【实际操作2】通过程序操作拷贝软件到D文件根目录; 【小心】复制的文件名要具体到程序的扩展名,和复制过去之后的文件名+扩展名;
FileInputStream 中的read()方法;
1、输入,将数据源的程序输入目的地:我们要编写程序; 操作为文件;
2、输出,将数据源程序的数据输出给制定目的地;
FileInputStream fin = null;
FileoutputStream fout = null;

fin = new FileInputStream fin("地址"); //try-catch-fnally;
fount = new FileoutputStream("D:/fuck.msi");
//文件过大的问题如何解决,减少内存消耗;
// int b = 0; read方法下一个数据字节如果达到文件末尾,返回-1;
// while( (b=fin.read()) != -1 ){ // read()一个字节一个字节的传;【缺陷】太慢
// fout.write(b);
【改进方案】
使用规定复制速度: byte[] b = new byte[1024];
while( (fin.read(b)) != -1 )
}----【 新的缺陷】:必须是数组b个数(1024)的整数倍;
改进方案】:
FileInputStream fin = null;
FileoutputStream fout = null;

fin = new FileInputStream("地址"); //try-catch-fnally;
fount = new FileoutputStream("D:/fuck.msi");

byte[] b = new byte[1024];
int lenght = 0 ;
while( ((length=fin.read(b)) != -1 ){
fout.write(b,0,length); //改写write;
fout.flush(); //强制冲刷行为;没放满也强制刷出去,大数据量、缓冲区的流都要加这个代码;
}

序列化的目的  :
1、以某种存储形式使自定义 对象持久化;  
2、将对象从一个地方传递到另一个地方。(相对Properties,性能更大的提升,信息以二进制形式存储);
3、使程序更具维护性;

【实际操作3-1】节点流和处理流如何对接合用; --对象序列化;
【小心】try-catch,可以用抛出,try-catch,加catch;
简写:将节点流new进去加入处理流的形参中,这样只是用一次,不用再关闭;方法:WriteObject();
添加标识接口:serializable,标识接口代表允许某项操作,无需实现方法和行为;
可以传输对象的集合,并通过形参传入Fileoutputstream的对象,形参传入存储地址;
1、构建学生类(属性-姓名、学号 构造器 get/set方法 修改toString方法方便打印功能; ) public class Student implements Serializable{}
2、在操作类中书写序列化代码:
HashMap<String, Student> allStus = new HashMap<String, Student>();
allStus.put("zhang3", new Student("zhang3",23));
allStus.put("li4", new Student("li4",21));
ObjectOutputStream oout = null;//对象输出流:把对象转换成二进制流输出
try {
oout = new ObjectOutputStream( new FileOutputStream( "student.data" ));
oout. writeObject( allStus);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(oout != null){
try {
oout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

【实际操作3-2】节点流和处理流如何对接实例化对象; --对象反序列化;
【小心】
1、读取,需要Student类与写入的类是一样的,不能再属性上任何有修改;
2、读用readObject();读出来的对象要进行强制类型转换,转换后将其赋值;
3、实际使用中数据类型要注意使用 data 、 txt ;
【实际 HashMap<String, Student> allStus = null;
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(" student.data"));
allStus = (HashMap<String, Student>)ois. readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally{
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(allStus.get("zhang3"));
System.out.println(allStus.get("li4"));
}

}

【细节】是不是所有的对象都可以进行传输:
1、要序列化一个类,除了这个类要实现序列化接口,这个类的每个属性(基本数据类型都实现了序列化的 ,自定义类型需要自己去实现接口);因此,JAVAbean规范应该实现serializable接口;
//public class Address implements Serializable:学生的地址属性实现序列化功能;//
2、不想序列化:通过 transient关键字对属性进行修饰;
3、序列化的类必须和反序列化的类保持一致 ;不能进行修改;
4、集合对象都实现了接口serializable,也可以进行直接进行序列化和反序列化;

操作ATM机:
【问题点】:ATM机刚启动,是没有初始化文件的,这个时候我们怎么去读取这个信息呢?--做假数据; 在哪里做假数据呢?在catch块内做!
【犯错点】:1、管道对接时不传数据:处理流初始化的 形参里面加节点流,节点流里面写路径;
2、架设好管道之后用write 将信息通过形参传入,开始写;




【思考】:为什么InputStream.read()读取一个byte却返回一个int呢?
InputStream.read()返回一个unsigned byte [0 - 255],而 Java 里面没有这个类型,所以用int接收。
byte的范围是[-128,127],所以如果read()返回的数在[128,255]的范围内时,则表示负数,即
(byte)128=-128
(byte)129=-127
(byte)255=-1
所以如果read()返回的是byte的话,那就会有负数。而"返回-1意味着结束",这个信息量用byte是无法表达的,所以必须用int。
1、字节流的后面要返回一个值,超过了byte的表达范围; byte表示-1(10000001) short(1000000000000001) 区分了手工-1和byte:-1;
2、外部使用方便,返回int,与int类型做比较外部操作者更方便;(外部默认为int);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值