第 21 单元:I/O

测试您的理解情况

返回到第 21 单元

  1. 对或错:在创建 File 对象来表示一个文件之前,该文件必须存在于磁盘上。

    答案:

  2. 哪句话最恰当地描述了字符流
    1. 字符流是 8 位流,用于通过 ByteArrayProcessor 接口从文件中读取数据并写入内存中。
    2. 字符流不应用于读取二进制数据。
    3. 字符流主要用于读取和写入文本文件。
    4. 字符流是 16 位流,用于通过 ReaderWriter 子类在文件中读取和写入数据。
    5. 上述选项都不是
  3. 哪句话最恰当地描述了为什么使用 BufferedReader
    1. 使用 BufferedReader 包装 OutputStreamWriter,可以通过缓存输入和输出来帮助它更高效地处理 16 位字符流。
    2. 结合使用 StreamReaderStreamWriter 时,必须小心不要跨越流,
    3. 当用作 InputStreamReader 的包装器时,BufferedReader 通过缓存输入来帮助它更高效地处理 16 位字符流。
    4. BufferedReader 绝不应用于从输入流读取数据。
    5. 上述选项都不是
  4. 创建一个名为 lorem.txt 的文件,其中包含 lorem ipsem 的前 250 个单词(可以使用 generator.lorem-ipsum.info 或类似网站生成此文本)。将该文件保存到 Java 项目的根目录。现在编写一个名为 Unit21 的类,其中包含一个名为 readFile() 的方法,该方法读取文件,使用 JDK Logger 实例打印它的内容,并将(包含文件内容的)String 返回给调用方。

    编写一个名为 Unit21Test 的 JUnit 类作为测试平台。

    要考虑的问题:
    • 您如何指定 readFile() 要读取的文件?
    • 您如何处理异常?
    • 如何确保在完成时关闭了所有文件资源?

    解决方案:

    lorem.txt
    Lorem ipsum dolor sit amet, fugit consetetur efficiantur nec eu, mea agam ridens vocibus an, falli errem eam ut. Minim voluptatibus in qui, no nec tibique perpetua imperdiet. Sententiae dissentias no vim, est cu mundi dicam eloquentiam, iudico aliquando cu cum. Ea eum inimicus recteque philosophia, mei mnesarchum adversarium eu. Velit possim definitiones mea ex, ad quem expetenda scripserit pro. Saepe utinam omittam est id, te eos ubique tritani.
    
     Id quas accumsan reprehendunt cum, in agam luptatum adversarium usu. Vix no errem voluptua lucilius. Eum hinc singulis no. Ea doctus nostrum aliquando mei.
    
     Augue vocent cum eu. Usu modo eius vulputate et, ea ius fabulas pericula voluptatum. Ne dicta laoreet sed, id amet forensibus nec. Ne mentitum persequeris complectitur sit. Est vocent virtute necessitatibus in, harum deleniti maluisset ex est, vix ea intellegam interpretaris.
    
     Omnis dicant facete sed eu. Ei equidem minimum concludaturque pri, dolor iudico eum ea, at porro scripta adolescens eum. Wisi illud ludus nam an. Ad vis possit intellegam adversarium. Ea solet soluta usu, ut usu zril audiam recteque. In repudiare quaerendum consequuntur mea, mea an odio placerat.
    
     Sea id sale aliquando, duo sint consectetuer definitionem no, et cum velit vocibus. Ex sale aperiri conceptam cum, ut ullum solet liberavisse sea. Quaeque platonem te sed, sanctus fastidii qui te, at doctus molestiae voluptaria usu. At quo lucilius disputando. Te qui munere officiis, cum te graeci bonorum. Per ne nostro sententiae, odio debitis eam cu.
    
     At nec iisque tamquam eligendi, cum an malis debet tractatos. Mea noster corpora.
    readFile()
    public String readFile(String fileName) {
       
       String ret;
       StringBuilder sb = new StringBuilder();
       
       File file = new File(fileName);
       int lineNumber = 0;
       // try with-resources will close resources when done
       try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
          String line = reader.readLine();
          while (line != null) {
             sb.append(line);
             sb.append('\n');
             // Read the next line
             line = reader.readLine();
          }
       } catch (IOException e) {
          log.severe("IOException occurred: " + e.getLocalizedMessage());
       }
       
       ret = sb.toString();
       log.info("File contents:\n" + ret);
       
       return ret;
    }
    JUnit test
    private static final String INPUT_FILE_NAME = "./lorem.txt";
    
    @Test
    public void testReadFile() {
       Unit21 classUnderTest = new Unit21();
       
       classUnderTest.readFile(INPUT_FILE_NAME);      
       
    }
  5. 将一个名为 writeFile() 的方法添加到问题 4 中的 Unit21 类,该方法将您读取的文件写入到一个名为 lorem2.txt 的新文件。向 Unit21Test 添加一个新测试方法作为测试平台。备注:您在问题 4 的解决方案中解决的问题同样也适用于输出流。

    解决方案:

    writeFile
    public void writeFile(String fileName, String fileContents) {
       
       File file = new File(fileName);
       
       try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)))) {
          writer.write(fileContents);
       } catch (IOException e) {
          log.severe("IOException occurred: " + e.getLocalizedMessage());
       }
       
    }
    JUnit test
    @Test
    public void testWriteFile() {
       String fileName = "./lorem2.txt";
       
       Unit21 classUnderTest = new Unit21();
       
       String fileContents = classUnderTest.readFile(INPUT_FILE_NAME);
       classUnderTest.writeFile(fileName, fileContents);
    }
    lorem2.txt
    Lorem ipsum dolor sit amet, fugit consetetur efficiantur nec eu, mea agam ridens vocibus an, falli errem eam ut. Minim voluptatibus in qui, no nec tibique perpetua imperdiet. Sententiae dissentias no vim, est cu mundi dicam eloquentiam, iudico aliquando cu cum. Ea eum inimicus recteque philosophia, mei mnesarchum adversarium eu. Velit possim definitiones mea ex, ad quem expetenda scripserit pro. Saepe utinam omittam est id, te eos ubique tritani.
    
     Id quas accumsan reprehendunt cum, in agam luptatum adversarium usu. Vix no errem voluptua lucilius. Eum hinc singulis no. Ea doctus nostrum aliquando mei.
    
     Augue vocent cum eu. Usu modo eius vulputate et, ea ius fabulas pericula voluptatum. Ne dicta laoreet sed, id amet forensibus nec. Ne mentitum persequeris complectitur sit. Est vocent virtute necessitatibus in, harum deleniti maluisset ex est, vix ea intellegam interpretaris.
    
     Omnis dicant facete sed eu. Ei equidem minimum concludaturque pri, dolor iudico eum ea, at porro scripta adolescens eum. Wisi illud ludus nam an. Ad vis possit intellegam adversarium. Ea solet soluta usu, ut usu zril audiam recteque. In repudiare quaerendum consequuntur mea, mea an odio placerat.
    
     Sea id sale aliquando, duo sint consectetuer definitionem no, et cum velit vocibus. Ex sale aperiri conceptam cum, ut ullum solet liberavisse sea. Quaeque platonem te sed, sanctus fastidii qui te, at doctus molestiae voluptaria usu. At quo lucilius disputando. Te qui munere officiis, cum te graeci bonorum. Per ne nostro sententiae, odio debitis eam cu.
    
     At nec iisque tamquam eligendi, cum an malis debet tractatos. Mea noster corpora.
  6. 改进问题 4 的解决方案,让每行的长度不超过 maxCharactersPerLine 字符数。(在到达第 maxCharactersPerLine 个字符时,可以尝试保留字。)编写 JUnit 测试,指定 80 作为 maxCharactersPerLine 的值。
    解决方案:
    public String readFileFormatWithMaxCharactersPerLine(String fileName, int maxCharactersPerLine) {
       String ret;
       StringBuilder sb = new StringBuilder();
       
       File file = new File(fileName);
       int lineNumber = 0;
       // try with-resources will close resources when done
       try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
          String line = reader.readLine();
          while (line != null) {
             line = formatLine(line, maxCharactersPerLine);
             sb.append(line);
             sb.append('\n');
             // Read the next line
             line = reader.readLine();
          }
       } catch (IOException e) {
          log.severe("IOException occurred: " + e.getLocalizedMessage());
       }
       
       ret = sb.toString();
       log.info("File contents:\n" + ret);
       
       return ret;
    }
    
    private String formatLine(String inputString, int maxCharactersPerLine) {
       String ret;
       
       StringBuilder sb = new StringBuilder();
    
       
       int currentCharacterIndex = 0;
       while (currentCharacterIndex < inputString.length()) {
          for (int aa = 0; aa < maxCharactersPerLine; aa++, currentCharacterIndex++) {
             if (currentCharacterIndex < inputString.length()) {
                sb.append(inputString.charAt(currentCharacterIndex));
             } else {
                break;
             }
          }
          sb.append('\n');
       }
       ret = sb.toString();
       return ret;
    }
    JUnit test
    @Test
    public void testReadFileFormatWithMaxCharactersPerLine() {
       Unit21 classUnderTest = new Unit21();
       
       classUnderTest.readFileFormatWithMaxCharactersPerLine(INPUT_FILE_NAME, 80);
    }
    Lorem ipsum text (no-preserve words)
    Lorem ipsum dolor sit amet, fugit consetetur efficiantur nec eu, mea agam ridens
     vocibus an, falli errem eam ut. Minim voluptatibus in qui, no nec tibique perpe
    tua imperdiet. Sententiae dissentias no vim, est cu mundi dicam eloquentiam, iud
    ico aliquando cu cum. Ea eum inimicus recteque philosophia, mei mnesarchum adver
    sarium eu. Velit possim definitiones mea ex, ad quem expetenda scripserit pro. S
    aepe utinam omittam est id, te eos ubique tritani.
    
    
     Id quas accumsan reprehendunt cum, in agam luptatum adversarium usu. Vix no err
    em voluptua lucilius. Eum hinc singulis no. Ea doctus nostrum aliquando mei.
    
    
     Augue vocent cum eu. Usu modo eius vulputate et, ea ius fabulas pericula volupt
    atum. Ne dicta laoreet sed, id amet forensibus nec. Ne mentitum persequeris comp
    lectitur sit. Est vocent virtute necessitatibus in, harum deleniti maluisset ex 
    est, vix ea intellegam interpretaris.
    
    
     Omnis dicant facete sed eu. Ei equidem minimum concludaturque pri, dolor iudico
     eum ea, at porro scripta adolescens eum. Wisi illud ludus nam an. Ad vis possit
     intellegam adversarium. Ea solet soluta usu, ut usu zril audiam recteque. In re
    pudiare quaerendum consequuntur mea, mea an odio placerat.
    
    
     Sea id sale aliquando, duo sint consectetuer definitionem no, et cum velit voci
    bus. Ex sale aperiri conceptam cum, ut ullum solet liberavisse sea. Quaeque plat
    onem te sed, sanctus fastidii qui te, at doctus molestiae voluptaria usu. At quo
     lucilius disputando. Te qui munere officiis, cum te graeci bonorum. Per ne nost
    ro sententiae, odio debitis eam cu.
    
    
     At nec iisque tamquam eligendi, cum an malis debet tractatos. Mea noster corpor
    a.
  7. 改进问题 6 的解决方案,防止截断包含第 maxCharactersPerLine 个字符的单词。而在下一行输出该单词(和任何后续单词)。这类似于文字处理程序的工作。编写 JUnit 测试,指定 80 作为 maxCharactersPerLine 的值。提示:更简单的方法可能是,一次一个单词地处理当前行,检查当前单词是否导致该行超出 maxCharactersPerLine,如果超出,则将该单词放在下一行。
    解决方案:
    public String readFileFormatWithMaxCharacterPerLinePerserveWords(String fileName, int maxCharactersPerLine) {
       String ret;
       StringBuilder sb = new StringBuilder();
       
       File file = new File(fileName);
       // try with-resources will close resources when done
       try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
          String line = reader.readLine();
          while (line != null) {
             line = formatLinePreserveWords(line, maxCharactersPerLine);
             sb.append(line);
             // Read the next line
             line = reader.readLine();
          }
       } catch (IOException e) {
          log.severe("IOException occurred: " + e.getLocalizedMessage());
       }
       
       ret = sb.toString();
       log.info("File contents: " + ret);
       
       return ret;
    }
    private String formatLinePreserveWords(String inputString, int maxCharactersPerLine) {
       String ret;
       
       StringBuilder sb = new StringBuilder();
       
       int currentCharacterIndex = 0;
       while (currentCharacterIndex < inputString.length()) {
          int currentLineIndex = 0;
          while (currentLineIndex < maxCharactersPerLine) {
             String word = fetchNextWord(inputString, currentCharacterIndex, currentLineIndex, maxCharactersPerLine);
             if (word != null) {
                currentCharacterIndex += word.length();
                currentLineIndex += word.length();
                sb.append(word);
             } else {
                break;
             }
          }
          sb.append('\n');
       }
       
       ret = sb.toString();
       return ret;
    }
    
    private String fetchNextWord(String inputString, int currentCharacterIndex, int currentLineIndex, int maxCharactersPerLine) {
       String ret = null;
       
       StringBuilder sb = new StringBuilder();
       while (currentCharacterIndex < inputString.length() && currentLineIndex < maxCharactersPerLine) {
          char currentCharacter = inputString.charAt(currentCharacterIndex);
          currentCharacterIndex++;
          currentLineIndex++;
          sb.append(currentCharacter);
          if (Character.isWhitespace(currentCharacter) || currentCharacterIndex == inputString.length()) {
             ret = sb.toString();
             break;
          }
       }
       return ret;
    }
    JUnit test
    @Test
    public void testReadFileFormatWithMaxCharactersPerLinePreserveWords() {
       Unit21 classUnderTest = new Unit21();
       
       classUnderTest.readFileFormatWithMaxCharacterPerLinePerserveWords(INPUT_FILE_NAME, 80);
    }
    Lorem ipsum text (preserve words)
    Lorem ipsum dolor sit amet, fugit consetetur efficiantur nec eu, mea agam 
    ridens vocibus an, falli errem eam ut. Minim voluptatibus in qui, no nec 
    tibique perpetua imperdiet. Sententiae dissentias no vim, est cu mundi dicam 
    eloquentiam, iudico aliquando cu cum. Ea eum inimicus recteque philosophia, mei 
    mnesarchum adversarium eu. Velit possim definitiones mea ex, ad quem expetenda 
    scripserit pro. Saepe utinam omittam est id, te eos ubique tritani.
    
    
     Id quas accumsan reprehendunt cum, in agam luptatum adversarium usu. Vix no 
    errem voluptua lucilius. Eum hinc singulis no. Ea doctus nostrum aliquando mei.
    
    
     Augue vocent cum eu. Usu modo eius vulputate et, ea ius fabulas pericula 
    voluptatum. Ne dicta laoreet sed, id amet forensibus nec. Ne mentitum 
    persequeris complectitur sit. Est vocent virtute necessitatibus in, harum 
    deleniti maluisset ex est, vix ea intellegam interpretaris.
    
    
     Omnis dicant facete sed eu. Ei equidem minimum concludaturque pri, dolor 
    iudico eum ea, at porro scripta adolescens eum. Wisi illud ludus nam an. Ad vis 
    possit intellegam adversarium. Ea solet soluta usu, ut usu zril audiam 
    recteque. In repudiare quaerendum consequuntur mea, mea an odio placerat.
    
    
     Sea id sale aliquando, duo sint consectetuer definitionem no, et cum velit 
    vocibus. Ex sale aperiri conceptam cum, ut ullum solet liberavisse sea. Quaeque 
    platonem te sed, sanctus fastidii qui te, at doctus molestiae voluptaria usu. 
    At quo lucilius disputando. Te qui munere officiis, cum te graeci bonorum. Per 
    ne nostro sententiae, odio debitis eam cu.
    
    
     At nec iisque tamquam eligendi, cum an malis debet tractatos. Mea noster 
    corpora.

返回到第 21 单元