尚学堂__百战程序员__1573题------第九章 IO流技术

1、IO是什么意思? data source是什么意思?

        Input,Output;输入与输出

        data source:数据源

2、字节流和字符流有什么区别?输入流和输出流有什么区别?

        字符流和字节流是流的一种划分,按照处理流的数据单位进行的划分。

        两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,

        输入使用的是InputStream,在字符流中输出主要是使用Writer类完成,

        输入流主要使用Reader类完成。这四个都是抽象类。

字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。

字节流是最基本的,所有的InputStrem和OutputStream的子类都是字节流,主要用在处理二进制数据,它是按字节来处理的。

但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的编码来处理,也就是要进行字符集的转化,这两个之间通过 InputStreamReader,OutputStreamWriter(转换流)来关联,实际上是通过byte[]和String来关联的。

流就像管道一样,在程序和文件之间,输入输出的方向是针对程序而言,向程序中读入东西,就是输入流,从程序中向外读东西,就是输出流。输入流是得到数据,输出流是输出数据。

3、节点流和处理流有什么区别?

        节点流和处理流是流的另一种划分,按照功能不同进行的划分。

        节点流,可以从或向一个特定的地方(节点)读写数据。

        处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。

        如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

4、word文档能使用字符流操作吗?为什么?

        不能。因为word文档不是纯文本文件,除了文字还包含很多格式信息。不能用字符流操作。可以用字节流操作。

5、【上机】完成老师课堂上读入文件数据的代码:

        

public static void testReader(){
            File f = new File("d:a.txt");
        FileInputStream fils = null;
        try {
            fils = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        int m = 0;
        try {
            while((m = fils.read())!= -1){
                char c = (char)m;
                System.out.println(c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try{
                if(fils != null){
                    fils.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

6、解释下面代码的含义

while((m=fis.read())!=-1){
char c = (char) m;
System.out.print(c);
}

        通过上例得知fis是字节输入流对象,fis.read()是每次从指定文件读取一个字节,返回值是这个字节所代表的int类型的整数。如果读到文件结尾(没有内容可读了),那么返回-1。

        下面的代码是依次读取文件,每次一个字节,循环读取;每次读完后将返回的整数值(m)转成char类型的数据(强转)(从而知道每次读取的是什么字符),输出这个字符。直到读完为止。

7、流对象使用完后,一般要调用close方法关闭,释放资源。 这种做法对吗?

        对

8、【上机】完成老师写文件的操作:

        

static void testWrite(){
        FileOutputStream fos = null;
        String str = "sffsdfsdfsdfsdfsdfsdfsdf";
        try {
            fos = new FileOutputStream("d:/b.txt");
                /*for(int i=0;i<str.length();i++){
                fos.write(str.charAt(i));
            }*/
            fos.write(str.getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(fos!=null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

9、InputStream和OutputStream基本特点是?

       二者都是【字节】输入输出流的抽象父类。以字节为单位处理数据,每次读取/写入一个字节。适合处理二进制文件,如音频、视频、图片等。实现类有FileInputStream和FileOutputStream等。

10、Reader和Writer的基本特点是?

        二者都是【字符】输入输出流的抽象父类。以字符为单位处理数据,每次读取/写入一个字符。适合处理文本文件。实现类有FileReader和FileWriter等

11、FileInputStream和OutputStream的基本作用是?

        二者都是【字节】输入输出流的实现类,其抽象父类是InputStream和OutputStream。以字节为单位处理数据,每次向/从指定文件读取/写入一个字节。适合处理二进制文件,如音频、视频、图片等。

12、FileReader和FileWriter的作用是?

        二者都是【字符】输入输出流的实现类,其抽象父类是Reader和Writer。以字符为单位处理数据,每次向/从指定文件读取/写入一个字符。适合处理文本文件。

13、【上机】完成文件的copy代码

static void copyCode(){
    File file = new File("e:\\picture1.jpg");
    try (InputStream is = new FileInputStream(file)) {
        File file1 = new File("e\\picture2.jpg");
        OutputStream os = new FileOutputStream(file1);

        int b = 0;

        while((b = is.read())!= -1){
            os.write(b);
        }
        os.close();
        is.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

14、BufferInputStream和BufferedOutputStream的特点是?

15、【上机】使用BufferedReader和BufferedWriter实现文本文件的拷贝。

16、PrintStream打印流经常用于什么情况? System.out 是不是打印流?

17、【上机】实现字节数组和任何基本类型和引用类型执行的相互转换

18、DataInputStream和DataOutputStream的特点是?

19、【上机】使用ObjectInputstream和ObjectOutputStream实现将某个对象存储
        到硬盘上,然后再读到程序中。

20、中文乱码是怎么造成的?

        字符流的读写根据需要设置编码方式,编码方式设置不当会出现中文乱码。

21、unicode字符集是几个字节表示一个字符?为什么需要utf-8?

        Unicode字符集中2个字节表示一个字符。

        参考:https://blog.csdn.net/jlfw/article/details/6384057  为什么需要utf-8

22、序列化和反序列化指的是什么?

        1) 序列化:
        将对象以byte流的形式写入到文件中->序列化;
        将要被序列化的对象的类要实现Serializable接口:
        publicclassUserimplements Serializable {
        //略;
        }
        User实现了这个接口,代表User这个类的对象具有了将对象以byte流的形式写进文件的功能。

   (2) 反序列化:
        将文件中的数据以byte流的形式读到程序中来,依然是一个对象反序列化。

23、想序列化某个类的对象,该类必须实现Serializable接口吗?

        要序化的对象必须实现Serializable接口,以启动序列化的功能。

24、说说Serializable接口的特点。

1. 需要被序列化的对象的类必须实现Serializable接口。
2. 给类加个序列化编号,即给类定义一个标记,如:
public static final long serialVersionUID=1L;
新的修改后的类还可以操作曾经序列化的对象。
3、静态是不能被序列化的,
序列化只能对堆中的对象进行序列化 ,不能对”方法区”中的对象进行序列化。
4、不需要序列化的字段前加 transient,如:
private transient String password;

25、transient的作用是?

不希望序列化的属性,可以添加transient关键字;
密码字段是非常敏感的字段,所在在序列化时,不允许写到文件:
private transient String password;

26、【上机】完成目录的copy代码(结合递归算法)

        

 /**
     * CopyDocJob定义了实际执行的任务,即
     * 从源目录拷贝文件到目标目录
     */
    public static void main(String[] args) throws IOException {
        copyDirectiory("d:/301sxt","d:/301sxt2");
    }
    /**
     * 复制单个文件
     * @param sourceFile 源文件
     * @param targetFile 目标文件
     * @throws IOException
     */
    private static void copyFile(File sourceFile,File targetFile)throws IOException{
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
// 新建文件输入流
        inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
// 新建文件输出流
        outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));

//        缓冲数组
        byte[] b = new byte[1024 * 5];
        int len;
        while((len = inBuff.read(b))!= -1){
            outBuff.write(b,0,len);
        }
//        刷新缓冲的输出流
        outBuff.flush();

        if(inBuff != null){
            inBuff.close();
        }
        if(outBuff != null){
            outBuff.close();
        }
    }
    /**
     * 复制目录
     * @param sourceDir 源目录
     * @param targetDir 目标目录
     * @throws IOException
     */
    private static void copyDirectiory(String sourceDir, String targetDir) throws IOException {
//        检查源目录
        File fSourceDir = new File(sourceDir);
        if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
            return ;
        }
//        检查目标目录,如不存在则创建
        File fTargetDir = new File(targetDir);
        if(!fTargetDir.exists()){
            fTargetDir.mkdirs();
        }
//        遍历源目录下的文件或者目录
        File[] file = fSourceDir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if(file[i].isFile()){
//                源文件
                File sourceFile = file[i];
//                目标文件
                File targetFile = new File(fTargetDir,file[i].getName());
                copyFile(sourceFile,targetFile);
            }
//            递归复制子目录
            if(file[i].isDirectory()){
//                准备复制的源文件夹
                String subSourceDir = sourceDir + File.separator+file[i].getName();
//                准备复制的目标文件夹
                String subTargetDir = targetDir + File.separator + file[i].getName();
                copyDirectiory(subSourceDir,subTargetDir);
            }
        }
    }

27、【上机】假设从入学开始所有书写的Java代码都在d:/sxtjava文件夹下,包括多

     级子文件夹。使用IO流获取从入学开始,到目前为止已经写了多少行Java代码。

class CountDir{
    private int count;
    /**
     * 统计一个java文件的行数
     */
    private void countLine(File sourceFile) throws IOException {
        BufferedReader br = null;

        try {
            br = new BufferedReader(new FileReader(sourceFile));
            while (br.readLine() != null){
                count++;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            br.close();
        }
    }
    /**
     * 统计一个目录下所有Java文件的行数
     */
    private void countDir(String sourceDir) throws IOException {
//        检查源目录
        File fSourceDir = new File(sourceDir);
        if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
            System.out.println("源目录不存在");
            return;
        }

//        遍历目录下的文件或目录
        File[] file = fSourceDir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if(file[i].isFile()){
                if(file[i].getName().toLowerCase().endsWith(".java")){
                    countLine(file[i]);
                }
            }
//            递归统计代码行数
            if(file[i].isDirectory()){
                String subSourceDir = sourceDir + File.separator + file[i].getName();
//                统计子目录
                countDir(subSourceDir);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        CountDir tcd = new CountDir();
        tcd.countDir("d:/java");
        System.out.println(tcd.count);
    }
}

28、【上机】下载并自学apache commons中的IO工具包。

感兴趣的看一看这篇博文!

https://www.cnblogs.com/softidea/p/4279576.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值