文件和流

IO作用:解决设备和设备之间数据传输问题,内存->硬盘,硬盘->内存,键盘数据->内存
数据存到硬盘上,就做到了永久保存,数据一般是以文件形式保存到硬盘上,sun用File描述文件文件夹
File类的构造方法
new File(String pathname);
通过将给定路径来创建一个新File实例。
new File(String parent, String child); 根据parent路径名字符串和child路径名创建一个新File实例。
new File(File parent, String child); 根据parent抽象路径名和child路径名创建一个新File实例。
File类的常用方法
关于路径
windows下级用"\"
linux下级用“/”
File类常用方法
创建:
createNewFile() 在指定位置创建一个空文件,成功就返回true,如果已存在就不创建然后返回false
mkdir() 在指定位置创建目录,这只会创建最后一级目录,如果上级目录不存在就抛异常。
mkdirs() 在指定位置创建目录,这会创建路径中所有不存在的目录。
renameTo(File dest) 重命名文件或文件夹,也可以操作非空的文件夹,文件不同时相当于文件的剪切,剪切时候不能操作非空的文件夹。移动/重命名成功则返回true,失败则返回false。
renameTo()重命名,如果源文件和目标文件在同一级下,作用是重命名,如果目标文件和源文件不是在同一文件夹下,作用是剪切,且不能操作文件夹
删除:
delete() 删除文件或一个空文件夹,如果是文件夹且不为空,则不能删除,成功返回true,失败返回false。
判断:
exists() 文件或文件夹是否存在。
isFile() 是否是一个文件,如果不存在,则始终为false。
isDirectory() 是否是一个目录,如果不存在,则始终为false。
isHidden() 是否是一个隐藏的文件或是否是隐藏的目录。
isAbsolute() 测试此抽象路径名是否为绝对路径名。

获取:

getName() 获取文件或文件夹的名称,不包含上级路径。
getPath() 返回绝对路径
getAbsolutePath() 获取文件的绝对路径,与文件是否存在没关系
length() 获取文件的大小(字节数),如果文件不存在则返回0L,如果是文件夹也返回0L。
getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回null。
lastModified() 获取最后一次被修改的时间。
文件夹相关:
staic File[] listRoots() 列出所有的根目录(Window中就是所有系统的盘符)
list() 返回目录下的文件或者目录名,包含隐藏文件。对于文件这样操作会返回null。
list(FilenameFilter filter) 返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。
listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。对于文件这样操作会返回null。
listFiles(FilenameFilter filter) 返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。
流的分类
1、按方向
输入流
输出流

2、按处理单位
字节流
就是用于读取文件的字节数据,读取到的数据不会进行任何处理
字符流
读取到的字节数据会转成读得懂的字符数据,读取的是以字符为单位 字符流=字节流+解码

InputStream抽象类输入字节流
FileInputStream读取文件数据的输入字节流
使用FileInputStream读取文件数据

    //方式1 无法完整读取文件数据
    public static void read1(){
        //1、找到目标文件
        File file = new File("f:\\a.txt");
        FileInputStream fileInputStream = null;
        
        try {
            //2、建立数据的输入通道
            fileInputStream = new FileInputStream(file);
            //3、读取文件数据
            int content = fileInputStream.read();//返回的是读取的数据,没辞职会读取一个字节
            System.out.println("读到的内容"+(char)content);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //4、关闭资源(释放资源文件)
            try {
                fileInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
        //方式2 每次可以读一个字节数据,可以完整读取数据
    public static void read2(){
        //1、找到目标文件
        File file = new File("f:\\a.txt");
        FileInputStream fileInputStream = null;
        
        try {
            //2、建立数据的输入通道
            fileInputStream = new FileInputStream(file);
            //3、读取文件数据
            int content = 0;//用于保存读到的数据
            while((content = fileInputStream.read()) != -1){//read()方法如果读到-1,表示结束
                System.out.print((char)content);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //4、关闭资源(释放资源文件)
            try {
                fileInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    }

但是方式2的效率又不高,就像你给全班同学买水,每次买一瓶

    //方式3 使用字节数组
    public static void read3(){
        //1、找到目标文件
        File file = new File("f:\\a.txt");
        FileInputStream fileInputStream = null;
        
        try {
            //2、建立数据的输入通道
            fileInputStream = new FileInputStream(file);
            //3、读取文件数据
            byte[] buf = new byte[1024];
            int length = fileInputStream.read(buf);//先把读取到的数据存储到字节数组中,然后返回本次读取到的字节数
            System.out.println("新生成的字符串"+new String(buf,0,length));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //4、关闭资源(释放资源文件)
            try {
                fileInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

如果文件够大,法三也不好

//方式4 使用循环配合缓冲读取数据
    public static void read4(){
        //1、找到目标文件
        File file = new File("f:\\a.txt");
        FileInputStream fileInputStream = null;
        
        try {
            //2、建立数据的输入通道
            fileInputStream = new FileInputStream(file);
            //3、读取文件数据
            byte[] buf = new byte[1024];//缓冲字节数组越大效率越高,一般都是1024的倍数
            int length = 0;//记录本次读字节个数
            while((length = fileInputStream.read(buf)) != -1){
                System.out.print(new String(buf,0,length));
            }
            
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //4、关闭资源(释放资源文件)
            try {
                fileInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

如果相比较运行效率,可以在程序开始前和程序开始后各定义一个startTime和endTime,即

    //方式4 使用循环配合缓冲读取数据
    public static void read4(){
        long startTime = System.currentTimeMillis();
        //1、找到目标文件
        File file = new File("f:\\a.txt");
        FileInputStream fileInputStream = null;
        
        try {
            //2、建立数据的输入通道
            fileInputStream = new FileInputStream(file);
            //3、读取文件数据
            byte[] buf = new byte[1024];
            int length = 0;//记录本次读字节个数
            while((length = fileInputStream.read(buf)) != -1){
                System.out.print(new String(buf,0,length));
            }
            long endTime = System.currentTimeMillis();
            System.out.println(endTime-startTime);
            
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //4、关闭资源(释放资源文件)
            try {
                fileInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

现在来验证一下为何要释放资源
当打断点时删除文件,会提示无法删除

OutputStream所有输出字节流的父类
FileOutputStream向输出数据的输出字节流

//方式1 每次只能写一个字节的数据
    public static void write1(){
        //1、找到目标文件
        File file = new File("f:\\b.txt");
        FileOutputStream fileOutputStream = null;
        
        try {
            //2、建立数据的输出通道
            fileOutputStream = new FileOutputStream(file);
            //3、把数据写出
            fileOutputStream.write('h');
            fileOutputStream.write('l');
            fileOutputStream.write('l');
            fileOutputStream.write('o');
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
//方式2
    public static void write2(){
        //1、找到目标文件
        File file = new File("f:\\b.txt");
        FileOutputStream fileOutputStream = null;
        
        try {
            //2、建立数据的输出通道
            fileOutputStream = new FileOutputStream(file);
            //3、准备数据,把数据写出
            String str = "hllo";
            //4、把字符串转成字节数组
            byte[] buf = str.getBytes();
            fileOutputStream.write(buf);
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

FileOutputStream要注意的细节:
1. new FileOutputStream 的时候,如果目标文件不存在,那么会先创建目标 文件,然后再写入。
2. new FileOutputStream(file) 如果目标文件已经存在,那么会先清空 目标文件的数据,然后再写入新的数据.
3. 写入数据的时候如果需要以追加的形式写入,那么需要使用new FileOutputStream(file,true) 这个构造函数。
4. 使用write(int b)方法的时候,虽然参数接受的一个int类型的数据,但是实际上只会把数据的低八位写出,其他24位丢弃。

练习 拷贝图片

    public static void copyPic(){
        //找到目标文件
        File inFile = new File("F:\\37.jpg");
        File outFile = new File("F:\\37_1.jpg");
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        
        try {
            //建立数据通道
            fileInputStream = new FileInputStream(inFile);
            fileOutputStream = new FileOutputStream(outFile);
            //建立缓冲字节数组,边读边写
            byte[] buf = new byte[1024];
            int length = 0;//记录每次读取字节个数
            while((length = fileInputStream.read(buf)) != -1){//假设最后一次读了700个字节,最后数组中剩余的空间也会被拷贝
                fileOutputStream.write(buf,0,length);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //原则 先开后关,后开先关
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                fileInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

由上,我们可以看出缓冲带来的效率之快,因此sun公司设计了缓冲字节流,凡是缓冲流,都会以Buffered开头
BufferedInputStream 缓冲输入字节流 该类本质就是在类内部维护了大小为8kb的字节数组,凡是缓冲流都没有读写文件的能力,BuffereInputStream 的close方法实际上关闭的就是你传递进去的FileInputStream对象。

    public static void buffer1(){
        //1、找到目标文件
        File file = new File("f:\\b.txt");
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream = null;
        try {
            //2、建立数据的输入通道
            fileInputStream = new FileInputStream(file);
            //3、建立缓冲输入字节流
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            int content = 0;
            while((content = bufferedInputStream.read()) != -1){
                System.out.print((char)content);
            }
            
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                bufferedInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

BufferedOutputStream 缓冲输出流,为了提高写文件的效率

    public static void buffer2(){
        //1、找到目标文件
        File file = new File("f:\\b.txt");
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        
        try {
            //2、建立数据的输出通道
            fileOutputStream = new FileOutputStream(file);
            //3、建立缓冲输出字节流
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            //4、写数据
            String str = "hello world";
            bufferedOutputStream.write(str.getBytes());
            bufferedOutputStream.flush();//把缓冲字节数组的数据写到硬盘中
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                bufferedOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    }

BufferedOutputStream 需要注意的事项: BufferedInputStream

1. 使用BufferedOutputStream的write方法时候,数据其实是写入了BufferedOutputStream内部维护的字节数组中,只有你调用
BufferedOutputStream的close方法或者是flush方法数据才会真正的写到硬盘上去或者内部维护的字节数组已经存储满数据了,这时候
数据也会写到硬盘上去。

2/. BufferedOutputStream 的close方法实际上关闭的就是你传入的OutputStream对象的close方法。

练习 利用缓冲输入输出字节流拷贝图片

    public static void copyPic1(){
        File inFile = new File("F:\\37.jpg");
        File outFile = new File("F:\\37_2.jpg");
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            fileInputStream = new FileInputStream(inFile);
            fileOutputStream = new FileOutputStream(outFile);
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            int content = 0;
            while((content = bufferedInputStream.read()) != -1){
                bufferedOutputStream.write(content);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                bufferedOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                bufferedInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

这里提一下,不需要每次循环都flush一下,可以用前后执行时间比对,会发现不加flush速度更快

字符流
向文件中写入中文

    public static void chineseWrite(){
        File file = new File("F:\\b.txt");
        String str = "今晚好";
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(str.getBytes());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

因为写字节流时字节流不具备编码和解码格式的限制,因此写中文不会乱码,但是,读取文件中数据会如何?

    public static void chineseRead(){
        File file = new File("F:\\b.txt");
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            int content = 0;
            while((content = fileInputStream.read()) != -1){
                System.out.print((char)content);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

会发现乱码,因为一个汉字有两个字节构成,而以上的读法每次只读一个字节

    public static void chineseRead(){
        File file = new File("F:\\b.txt");
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            int length = 0;
            byte[] buf = new byte[2];
            while((length = fileInputStream.read(buf)) != -1){
                System.out.print(new String(buf,0,length));
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

可以看出非常麻烦,因此引出字符流,字符流是指读取的数据是以字符为单位的,会把读到的字节数据转换成我们看的字符,字符流 = 字节流+编码(解码)
输入字符流
Reader 抽象类 所有输入字符流的基类
FileReader 读取文件数据的输入字符流

    //法1 每次只会读取一个字符数据
    public static void readTest1(){
        //1、找到目标对象
        File file = new File("F:\\b.txt");
        
        FileReader fileReader = null;
        
        try {
            //2、建立数据的输入通道
            fileReader = new FileReader(file);
            //3、读取文件数据
            int content = 0;
            while((content = fileReader.read()) != -1){//FileReader的read方法每次读取一个字符的数据,如果读到文件结束,返回-1
                System.out.print((char)content);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //法2 使用缓冲字符数组读取文件数据
    public static void readTest2(){
        //1、找到目标对象
        File file = new File("F:\\b.txt");
        FileReader fileReader = null;
        try {
            //2、建立数据的输入通道
            fileReader = new FileReader(file);
            //3、建立字符数组读取数据
            char[] cbuf = new char[1024];
            int length = 0;
            while((length = fileReader.read(cbuf)) != -1){
                System.out.print(new String(cbuf,0,length));
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

输出字符流
Writer抽象类 输出字符流的基类
FileWriter 向文件写出数据输出字符流

    public static void writeTest1(){
        //1、找到目标对象
        File file = new File("F:\\b.txt");
        FileWriter fileWriter = null;
        try {
            //2、建立数据输出通道
            fileWriter = new FileWriter(file);
            //3、准备数据
            String str = "现在雨停了";
            fileWriter.write(str);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

FileWriter 要注意的事项:
1. new FileWriter(file)的时候 , 如果目标文件不存在,那么会创建目标文件对象, 如果目标文件已经存在了,那么则不再重新创建。
2. 使用new FileWriter(file) 这个构造方法的时候,默认是会先清空文本的数据,然后再写入新的数据。如果需要追加数据则需要使用 new FileWriter(file,true)这个构造方法。
3. 使用FileWriter的write方法的时候,数据是写入了FileWriter内部维护的字符数组中,如果需要把数据真正的写到硬盘上去,需要调用flush方法或者 是close方法
或者是内部维护的字符数组已经满了,这时候也会写到硬盘上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,656评论 18 139
  • .NET Framework将文件视为数据流。流是一系列用字节表示的数据分组。数据流有底层存储介质,这些存储介质通...
    CarlDonitz阅读 669评论 0 0
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,378评论 0 4
  • IO流(Input Output) IO技术主要的作用是解决设备与设备之间 的数据传输问题。硬盘 -> 内存内存的...
    奋斗的老王阅读 4,275评论 1 48
  • 海天一色的风景画 画里有你的生活 时间定格,你笑颜如阳光下的向日葵 明快的看不见一丝忧伤 学着海鸥的自由 张开翅膀...
    不过花开阅读 147评论 0 0