------- android培训、java培训、期待与您交流! ----------
问题1:写在最前面,IO读取和写入的操作为什么在源码中是字节,而在操作中是int类型的呢?
IO流基础:底层操作都是字节,其实是int(运算时类型提升)
1再来一个自己理解:总结学习内容再比喻一下,流技术就和水管(字节流,字符流)一样,水管里都是有水滴(一个byte)在流动,但是这个管道是单向的,显而易见,生活中没有一个水管同时想不同的方向流,所以在拷贝文件时,我们现将水放入水桶(内存中的变量),再将水桶中的水搬去另外一个地方,互不干涉,就利用流完成了文件的操作,其实java很多问题都是通过第三方变量(中介)这个思想来实现的。
2流分类:
字节流
InputStream 高效流 BufferedInputStream
OutputStream BufferdeOurputStream
字符流
Reader 高效流 BufferedReader
Writer BufferedWriter
转换流(将字节转换为字符,是字符流的一个功能,所以要定义在字符流体系中)
InputStreamReader
OutputStreamWriter
3方法,操作概述:
1流存在是必须指定目的地:构造方法(文件地址),注意异常会发生;
2jvm操作开始:read(),writer(),开始读写
3判断有无完成的标志是字节有没有的标志是:-1;
4关闭资源:finaly{}中注意关闭的写法
练习代码1:// 将键盘输入的字符存到一个文档中
public class ZiJieLiu {
public static void main(String[] args) {
sysinToTxt();
}
// 将键盘输入的字符存到一个文档中
public static void sysinToTxt() {
//将键盘输入的字节流转换为字符缓冲流
BufferedReader buf=new BufferedReader((new InputStreamReader(System.in)));
BufferedWriter bufw=null;
try {
//拷贝到桌面的这个文件,没有就创建
bufw=new BufferedWriter(new FileWriter("C:\\Users\\WakeHibernate\\Desktop\\123\\copy.txt"));
} catch (IOException e1) {e1.printStackTrace();}
try {
String line = null;
while (true) {
line = buf.readLine();
//输入结束标记
if(line.equals("over"))
break;
//写
bufw.write(line);
//新的一行
bufw.newLine();}} catch (IOException e) {e.printStackTrace();}
finally{
if(buf!=null)
try {buf.close();
} catch (IOException e) {e.printStackTrace();}
if(bufw!=null)
try {bufw.close();} catch (IOException e) {
e.printStackTrace();
}}}
字节流总结,字节流在写出数据是不需要刷新
练习2
/**
* 编写程序,将指定目录下所有.java文件拷贝到另一个目的中,并将扩展名改为.txt
* 1什么时候该扩展名
* 2读取通道是怎么设置的
* 编写程序,将指定目录下所有.java文件拷贝到另一个目的中,并将扩展名改为.txt
* 源 E:\activitiwokspace\exam\src\com\itheima
* 目的:C:\Users\WakeHibernate\Desktop\copy
* 1将文件拷贝到集合当中
* 2将集合中的文件名封装为File对象写入到指定的目的当中
*/
public static void main(String[] args){
File yuanFile=new File("E:\\activitiwokspace\\exam\\src\\com\\itheima");
ArrayList<File> arrList=new ArrayList<File>();
coptToList(yuanFile,arrList);
File mudi=new File("C:\\Users\\WakeHibernate\\Desktop\\copy");
listToDesk(arrList,mudi);
}
//将集合拷贝到目的当中
private static void listToDesk(ArrayList<File> arrList, File mudi) {
//为什么要创建读取对象,因为arrList中存放的是抽象文件的路径名
BufferedReader br=null;
BufferedWriter bw=null;
if (!mudi.isDirectory()) {
mudi.mkdir();
//每循环一次就创建流对象吗
for (File f : arrList) {
try{
br=new BufferedReader(new FileReader(f.getAbsoluteFile()));
bw=new BufferedWriter(new FileWriter(mudi+"\\"+f.getName().replace(".java", ".txt")));
//写的时候出现了问题
String len=null;
while((len=br.readLine())!=null){
bw.write(len);
bw.newLine();
//缓冲流和字符流都需要缓冲,因为他们将水滴先存起来了
bw.flush();}
}catch (IOException e) {
e.printStackTrace();
}finally{
if(bw!=null){
try {bw.close();} catch (IOException e) {e.printStackTrace();}}
if(br!=null){
try {br.close();} catch (IOException e) {e.printStackTrace();}}}}}}
//拷贝到集合当中
private static ArrayList<File> coptToList(File dir,ArrayList<File> fileList) {
File[] dirs=dir.listFiles();
for (File f : dirs) {
if (f.isDirectory()) {
//递归判断是否还有子文件
coptToList(f,fileList);
}else{
if (f.getName().endsWith(".java")) {
fileList.add(f);}}}
return fileList;}}
练习2总结:何时该文件名,在输出的时候再改文件名,也可以直接将文件拷贝到目的地中,其中有File()文件
5其他常用流介绍
1PrintWriter: 向文本输出流打印对象的格式化表示形式,这个通常在ajax中向客户端发送部分数据非常常用
2对象序列化:在使用ObjectInputStream,相互传送对象是,要让自定义类型实现序列化接口,这个接口的常量值是根据类型中所有字段方法的值计算出来了,不会冲突, 保证对象在内存中的唯一性和一致性
3还有一些数据流,类型流,文件访问流等,通常不常用,但还是要了解一下,主要是字符流和字节流的使用,缓冲,转换功能
6File类:
个人理解:File类是一个文件,目录的抽象表述,就想我们eclipse在桌面创建的快捷方式一样,只是一个表示,他只是一抽象表示,所以要创建,判断还是要在看功能
常用的方法:
判断功能:
isFIle()是否具体文件,isDir()是否目录,canExecute()能否执行,exists()是否存在,canRead(),是否可读,canWrite();是否可写
创建:
creatNewFile()如果存在就不创建
删除:
delete()删除,deleteOnExit()放jvm退出时删除
获取:
getAbsolutePath()获取据对路径地址,getName()获取文件名 Long lengtf()获取文件大小
总结:
1对于最上面的问题我是这样理解的,这个答案针对基本类型的强转精度丢失等都是一个答案,因为jvm也是一个OS运行的一个程序,而操作系统我们通常有32位,64位之分,在安装操作系统的时候我们发现其实64位操作系统的安装文件名好像有一个x86-64,所以,我觉得底层还是32位的,计算机一次运算的最小单元是32为的,所以在读取字节的时候先将字节提升为int类型(因为int类型范围比byte范围大),所以返回的也是int类型,这样我们操作起来就不迷惑了;
2练习1中用到了转换流,并包装为高效流,这是装饰模式在流对象的应用,其中转换流可以设置字符编码;
3流操作过程中注意字符编码要一致,否则会出现乱码现象