• Java 学习记录(8) IO流


    一、Java中流的分类有哪些?

    • 流从读取类型上来看分为字节流和字符流。
    • 从流动方向上看又分为输入流和输出流两类。
    • 从流从发生的源头看分为节点流和过滤流。其中节点流:直接操作目标设备对应的流,如文件流,标准输入输出流。过滤流:继承带有关键字Filter的流用于包装操作节点流,方便读写各种类型的数据。

    二、字节流InputStream和OutputStream的子类分别有哪些?请举例说明其使用场景。与其对应的字符流分别有哪些?

    InputStreamOutputStream是两个抽象类,其子类分布如下:

    • FileinputStream 和FileOutputStream
     对应的字符流为  FileReader 和  FileWriter
    

    FileInputStream的作用在于通过指定文件路径的方式,将一个文件中的内容作为其他流的数据源,从而可以使用流的方式对文件进行读的操作;FileOutputStream的作用在于通过指定文件路径的方式,将一个文件作为其他流的输出目的地,从而可使用流的方式对文件进行写操作。

    • 字节数组流 ByteArrayInputStreamByteArrayOutputStream
    对应的字符流为 CharArrayReader CharArrayWriter
    

    字节数组流的作用是在字节数组和流之间搭建桥梁,ByteArrayInputStream的构造方法ByteArrayInputStream(byte[] buf)可以将字节数组构造成字节数组流的数据源,从而可以通过流的方式来读字节数组; ByteArrayOutputStream的作用在于可以将任意多字
    节的内容多次写入流中,最后整体转为一个字节数组。

    • 管道流PipedInputStreamPipedOutputStream
    对应的字符流为 PipedReader  PipedWriter
    

    管道用来把一个程序、线程和代码块的输出连接到另一个程序、线程和代码块的输入。管道输入流作为一个通信管道的接收端,管道输出流则作为发送端。管道流必须输入/输出并用,即在使用管道前,两者必须进行连接。

    • 对象流ObjectOutputStreamObjectInputStream
      能够输入/输出对象的流称为对象流
    • 过滤流FilterInputStreamFilterOutputStream
    对应的字符流为:FilterReader 和FileterWriter
    

    FilterInputStreamFilterOutputStream是两个抽象类,分别重写了父类InputStreamOutputStream的所有方法,对其他输入/输出流进行特殊处理,此外还提供了同步机制,使得某一时刻只有一个线程可以访问一个输入与输出流。要使用过滤流,首先必须把它连接到某个输人/输出节点流上。通常构造方法的参数中指定所要连接的节点流。

    FilterInputStream( InputStream in);
    FilterOutputStream( OutputStream out);
    

      

    • 缓冲流BufferedInputStreamBufferedOutputStream
    对应的字符流为:BufferedReader 和 BufferedWriter
    

    这两个类分别是FilterInputStreamFilterOutputStream的子类,实现了带缓冲的过滤流,它提供了缓冲机制,把节点流“捆绑”到缓冲流上,可以提高读写效率。使用于大文件的读写。

    • 数据流DatalnputStreamDataOutputStream
      这两个类分别是FilterInputStream 和FilterOutputStream的子类,它们以统一方式读出或写出boolean、int、long、double等基本数据类型。此外,还提供了字符串读写的方法。
    • 打印流PrintStream
    对应的字符流为PrintWriter
    

    它能在输出时自动完成两项功能:如果输出字符串,则完成字符的编码过程,如果有汉字,能将汉字自动转化为操作系统本身的字符集GBK;另外,如果其输出路径上接有缓冲流,当调用println方法或输出字符串中有换行标志时,则自动调用缓冲流的flush方法。
    在这里插入图片描述

    三、字节流与字符流的转化是怎样的?Java对此提供了哪些支持?

    字节流与字符流的转化桥梁在于类InputStreamReaderOutputStreamWriter

    • InputStreamReader 用于字节流->字符流
      它读取字节,并使用指定的编码将其解码为字符,它使用的字特集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
    构造方法:
    
    InputStreamReader (InputStream in)//创建一个使用默认字符集的InputStreamReader (InputStream in,String charsetName)//自己设定了
    

      

    • OutputStreamWriter 用于字符流->字节流。
      使用指定的编码将写入的字符编码为字节,它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
    构造方法:
    
     OutputStreamWriter(OutputStream out) 
    //OUtputstream 也是一个抽象类,真正做参数的是它的子类。例如:Fileoutputstream
    OutputStreamWriter(OutputStream out,String charstname)
                        后面的参数指定字符集。
    

      

    四、Java中的过滤流(流的装配)有什么作用?请举例说明常用的过滤流。

    过滤流的具体作用请看(二)中关于过滤流的介绍。
    常见的过滤流即为:BufferedInputStream 和BufferedOutputStream, 缓存作用,用于装配文件磁盘、网络设备、终端等读写开销大的节点流,提高读写性能。

    五、什么是对象的序列化和反序列化?Java对此提供了哪些支持?

    序列化: 对象的串行化(Serialization)将实现了Seriallizable接口的对象转换成一个字节序列。与之对应的反序列化就是把字节序列完全恢复为原来的对象。
    支持: ObjectInputStream类和ObjectOutputStream类。

    六、 Java的File类表示什么?有什么作用?

    File 类表示的其实是文件和目录的具体路径,即FilePath。可以通过File类来对文件或者目录的创建和后续的读写操作。
    具体请看下面的编程题:

    七、Java对文件的读写分别提供了哪些支持?

    读文件:FileInputStream FileReader
    写:FileOutputStream FileWriter
    提供对文件的随机访问支持:RandomAccessFile
    具体请看编程题中的3和4。

    八、编程题

    一、完成下面的代码,要求建立一个缓冲区,将字节输入流中的内容转化为字符串。

    代码如下(示例):

    //完成下面的代码,要求建立一个缓冲区,将字节输入流中的内容转化为字符串。
    import java.io.*;
    
    public class test3 {
        public static void main(String[]args){
            File file =new File("E:\name1.txt");
            try (FileInputStream fileInputStream = new FileInputStream(file)) {
                System.out.println(loadStream(fileInputStream));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static String loadStream(InputStream in) throws IOException {
            StringBuffer stringBuffer = new StringBuffer();
            InputStreamReader inputStreamReader = new InputStreamReader(in);
            char[]chars =new char[1024];
            int len;
            while((len=inputStreamReader.read(chars))!=-1){
                stringBuffer.append(String.valueOf(chars));
            }
            return String.valueOf(stringBuffer);
        }
    }
    }
    /*
    将数据读入字符数组中,然后利用StringBuffer类做中转站,将字符数组加入,最后就是把这个StringBuffer类转换为String返回
    */
    

      

    二、编写程序,将一个字符串转为字节数组输入流,将这个流中所有小写字母换成大写字母并写入字节数组输出流中,再将数组输出流转为字符串。

    代码如下(示例):

     1  2 /*
     3 * 编写程序,将一个字符串转为字节数组输入流,
     4 * 将这个流中所有小写字母换成大写字母并写入字节数组输出流中,
     5 * 再将数组输出流转为字符串*/
     6 
     7 import java.io.ByteArrayInputStream;
     8 import java.io.ByteArrayOutputStream;
     9 import java.util.Scanner;
    10 public class test4 {
    11     public static void main(String[]args){
    12         String str1;
    13         Scanner scanner = new Scanner(System.in);
    14         str1=scanner.nextLine();
    15         byte[]bytes=new byte[1024];
    16         bytes=str1.getBytes();
    17         try{
    18             ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
    19             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    20             int len;
    21             while((len=byteArrayInputStream.read())!=-1){
    22                 if(len>='a'&&len<='z'){
    23                     len=len+'A'-'a';
    24                 }
    25                 byteArrayOutputStream.write(len);
    26             }
    27             byteArrayInputStream.close();
    28             String string =byteArrayOutputStream.toString();
    29             System.out.println(string);
    30         } catch (Exception e) {
    31             e.printStackTrace();
    32         }
    33     }
    34 }
    35 
    36 /*
    37 利用字节数组输入流来读数据,每一次读取一个,并且同时做出转化,将小写转化为大写。再写入字节数组输出流,最后利用`toString`方法来转化为字符串,进行return
    38 */

    三、完成下面方法中的代码,方法中的参数为一个文本文件的名称,要求将文件中的内容转为字符串。

    代码如下(示例):

     1  2 /*
     3 *完成下面方法中的代码,方法中的参数为一个文本文件的名称,
     4 * 要求将文件中的内容转为字符串。
     5 * */
     6 
     7 import java.io.File;
     8 import java.io.FileInputStream;
     9 import java.io.FileNotFoundException;
    10 import java.io.IOException;
    11 public class test5 {
    12     public static void main(String[]args){
    13         String  string="E:\name1.txt";
    14         System.out.println(loadFile(string));
    15     }
    16     public static String loadFile(String filename){
    17         byte[] bytes = new byte[1024];
    18         int len;
    19         StringBuffer S = new StringBuffer();
    20         try {
    21             File file = new File(filename);
    22             FileInputStream fileInputStream = new FileInputStream(file);
    23             while((len=fileInputStream.read(bytes))!=-1){
    24                 String str1 = new String(bytes,0,len); //一次读取一个字符数组的内容,我们要做的就是把这一部分字符数组里的内容
    25                 S.append(str1);
    26             }
    27             fileInputStream.close();
    28         }catch(FileNotFoundException e) {
    29             e.printStackTrace();
    30         } catch (IOException e) {
    31             e.printStackTrace();
    32         }
    33         return String.valueOf(S);
    34     }
    35 }
    36 /*
    37 利用文件输入输出流,
    38 每一次读取一个字符数组的内容,并利用`toString`方法转化为字符串,再利用`StringBuffer`类的`append`方法进行拼接。直到读到文件末尾。
    39 最后就是把StringBuffer类转换为String。
    40 
    41 */

    四、完成下面方法中的代码,将字符串contents中的内容写入文件filename中。

    static public boolean saveFile(String filename, String contents) {}
    代码如下(示例):

     1  2 /*
     3 * 完成下面方法中的代码,将字符串contents中的内容写入文件filename中。
     4 * */
     5 import java.io.*;
     6 import java.util.Scanner;
     7 public class test6 {
     8     public static void main(String[]args) throws FileNotFoundException {
     9         Scanner scanner = new Scanner(System.in);
    10         String contents=scanner.nextLine();
    11         //这是要写入的字符串
    12         String filename ="E:\coding\JavaLearningCode\java输入输出流的编写\test6.txt";
    13        System.out.println(saveFile(filename,contents));
    14     }
    15     public static boolean saveFile(String filename, String contents) throws FileNotFoundException {
    16        try (FileOutputStream fileOutputStream = new FileOutputStream(filename)) {
    17            byte[] bytes=contents.getBytes();
    18            fileOutputStream.write(bytes);
    19        } catch (IOException e) {
    20            e.printStackTrace();
    21        }
    22         return true;
    23     }
    24 }
    25 /*
    26 先把字符串转化为字符数组,再利用字节输出流的写文件方法写入即可。
    27 
    28 */

    五、socket 套接字有一个方法getInputStream(),其含义是得到从网络上传过来的数据流。现要求编写一段程序,将接收的数据存入文件。

    代码如下(示例):

     1  2 
     3 import java.io.*;
     4 import java.net.Socket;
     5 
     6 /*
     7 socket 套接字有一个方法getInputStream()
     8 其含义是得到从网络上传过来的数据流。现要求编写
     9 一段程序,将接收的数据存入文件。
    10  */
    11 public class test7 {
    12     public static void main(String[]args) throws IOException {
    13         Socket socket=new Socket("127.0.0.1",4700);
    14         BufferedReader sin =new BufferedReader(new InputStreamReader(socket.getInputStream()));
    15         File file = new File("E:\coding\JavaLearningCode\java输入输出流的编写\test7.txt");
    16         FileOutputStream out = new FileOutputStream(file);
    17         BufferWriter bw=new BufferWriter(new OutputStreamWriter(out)); 
    18         String readline = sin.readLine();
    19         bw.write(readline);
    20         sin.close();
    21         bw.close();
    22         socket.close();
    23     }
    24 }
    25 /*
    26 利用字符输输入流和字符输出流来实现,
    27 构建字符输入流对象 sin和字符输出流对象 bw。其中用到了OutputStreamWriter和InputStreamReader 做中转。
    28 最后完成了读入和写。
    29 */

    六、编写程序实现文件查找功能。提供两个参数,第一个参数为查找的起始路径,第二个参数为要查找的文件名称。如果找到,则给出文件的完整路径,否则提示文件不存在。

    代码如下(示例):

     1 2 import java.io.File;
     3 public class test8 {
     4     public static void main(String args[]){
     5        String str1="E:\test1";
     6        String str2="1.txt";
     7        FindFile(String str1,String str2)
     8     }
     9     public static void FindFile(String str1,String str2){
    10         File file1 =new File(str1);
    11         File[] files=file1.listFiles();
    12         for(File file2:files){
    13             if(file2.isFile()){
    14                 String string1 = file2.getAbsolutePath();
    15                 int firstindex=string1.lastIndexOf('\');
    16                 String substring=string1.substring(firstindex+1);
    17                 if(substring.equals(str2)){
    18                     System.out.println(string1);
    19                     return;
    20                 }
    21             }else if(file2.isDirectory()){
    22                 String string = file2.getAbsolutePath();
    23                 FindFile(string,str2);
    24             }
    25         }
    26     }
    27 }
    28 /*
    29 先对起始路径构建Filec对象,并且利用`listFiles()`方法来得到所有的子目录,或者文件,下一步就是判断,是文件?是,则利用字符串拼接和比对`equals()`方法来判断文件名是否相同。
    30 否则,对于目录,我们继续向下递归。
    31 */

    七、利用串行化技术和Socket通信,将一个客户端构造的对象送到服务端,并输出该对象的属性值。

     1 --------第一个User类-----------------
     2 
    3 4 import java.io.Serializable; 5 public class User implements Serializable { 6 7 private static final long serialVersionUID = 1L; 8 String Name; 9 String Password; 10 User()//默认构造函数 11 { 12 Name="null"; 13 Password="00000"; 14 } 15 User(String name,String password)//带参数的构造函数 16 { 17 Name=name; 18 Password=password; 19 } 20 void setName(String name) {Name=name;} 21 void setPassword(String password) {Password=password;} 22 String getName() {return Name;} 23 String getPassword() {return Password;} 24 } 25 26 ----------------下面是第二个类,客户端------- 27 package 作业题9; 28 29 import java.io.*; 30 import java.net.Socket; 31 32 public class TalkClient { 33 public static void main(String[] args) throws IOException{ 34 Socket socket = null; 35 try { 36 socket = new Socket("127.0.0.1", 4700); 37 } catch (IOException e) { 38 e.printStackTrace(); 39 } 40 User u1 = new User(); 41 u1.setName("Tommy"); 42 u1.setPassword("1234567"); //赋值 43 //把对象串行化为可输出的形式,输入到Socket的输出流里面 44 ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); 45 out.writeObject(u1);//以串行化方式写入这个对象 46 System.out.println("successful!"); 47 out.flush(); 48 out.close();//超级重要,要是没有close来正常退出,服务器端就会被意外中止,导致出错。 49 } 50 } 51 52 53 -------------------------------下面是服务器端--------- 5455 56 import java.io.*; 57 import java.net.*; 58 59 public class MultiTalkServer { 60 public static void main(String[] args) throws ClassNotFoundException, IOException { 61 ServerSocket server; 62 Socket socket = null; 63 try { 64 server = new ServerSocket(4700); 65 socket = server.accept(); 66 ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); 67 System.out.println("连接成功!"); 68 User u2 = (User) in.readObject();//接受一个被串行化的对象,赋值给u2 69 System.out.println("Name: "+ u2.getName() + " Password: " + u2.getPassword()); 70 in.close(); 71 } catch (IOException e) { 72 e.printStackTrace(); 73 } 74 } 75 }
  • 相关阅读:
    作为一个新手程序员,该如何去挽救一个失败的项目?
    IOS查看APP的crash Log
    UITableView 性能优化(卡问题自检)
    ARC学习笔记(一)
    iPhone的UDID与push中使用的device token的关系
    跳转appstore的评分页面和软件的首页
    IOS项目Jenkins集成脚本举例
    jenkins集成学习心得
    学习设计模式心得
    网页跳转到APP
  • 原文地址:https://www.cnblogs.com/axchml/p/14099772.html
Copyright © 2020-2023  润新知