Java——缓冲读取

标签 java

我正在为自己开发一个程序,它展示了读取文本文件的所有不同方式。我用过 FileWriter 和 BufferedWriter。

我的问题是为什么 FileWriter 变量需要包装在 BufferedWriter 中。我在代码中经常看到这一点,在某些情况下,例如 int 包装在 Integer 中。这对我来说很有意义,但是将 FileWriter 包装在 BufferedWriter 中有什么好处。

    **FileWriter fWriter = new FileWriter(fileName);
    BufferedWriter bW = new BufferedWriter(fWriter);**

我在这个网站上找到了下面的代码,我通读了评论和答案,发现它有点帮助完整

我认为令人困惑的部分是文件有很多不同的缓冲读取。读取文件的最佳方式是什么以及为什么必须将它们包装在其他对象中。它可以方法支持吗?它会刷新缓冲区吗?它会提高速度吗? (可能不是)将文件包装在缓冲区中是否有一些很大的优势。

    FileWriter fWriter = new FileWriter(fileName);
    BufferedWriter bW  = new BufferedWriter(fWriter);

在上面的代码中,fWriter 是用文件名创建的。然后 fWriter 变量被“包装”到 BufferedWriter bW 变量中。将 FileWriter 包装到 BufferedWriter 中的真正目的是什么。

  ---------------------------------------------------------
  -        FileWriter fw = new FileWriter (file);         -
  -        BufferedWriter bw = new BufferedWriter (fw);   - 
  -        PrintWriter outFile = new PrintWriter (bw);    - 
  ---------------------------------------------------------

下面是我的完整文件程序。我真的只是对缓冲包装器有疑问,但我认为如果有人想要编译并运行它,我无论如何都会以这种方式发布它,那么他们真的应该不会遇到任何麻烦。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;

public class DDHExampleTextFileReader {
    List<String> lines = new ArrayList<String>();
    final static String FILE_NAME = "G:testFile.txt";
    final static String OUTPUT_FILE_NAME = "G:output.txt";
    final static Charset ENCODING = StandardCharsets.UTF_8;
    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

    public DDHExampleTextFileReader() {
       //Zero argument constructor
    }

    private void fileReadOne() {
        String fileName = "G:testFile.txt"; // The name of the file to open.
        String line = null; // This will reference one line at a time

        try {
            // FileReader reads text files in the default encoding.
            // FileReader is meant for reading streams of characters. 
            // For reading streams of raw bytes, consider using a FileInputStream.
            FileReader fileReader = new FileReader(fileName);
            // Always wrap FileReader in BufferedReader.
            BufferedReader bufferedReader = new BufferedReader(fileReader);

                while((line = bufferedReader.readLine()) != null) {
                    System.out.println(line);
                }   

            bufferedReader.close();             // Always close files.
        }
        catch(FileNotFoundException ex) {
            System.out.println(
                "Unable to open file '" + 
                fileName + "'");                
        }
        catch(IOException ex) {
            System.out.println("Error reading file '" + fileName + "'");    
            ex.printStackTrace();
            // Or we could just do this: 
            // ex.printStackTrace();
        }
    }

    private void fileReadTwo() {
         // The name of the file to open.
        String fileName = "G:testFile.txt";

        try {
            // Use this for reading the data.
            byte[] buffer = new byte[1000];

            FileInputStream inputStream = 
                new FileInputStream(fileName);

            // read fills buffer with data and returns
            // the number of bytes read (which of course
            // may be less than the buffer size, but
            // it will never be more).
            int total = 0;
            int nRead = 0;
            while((nRead = inputStream.read(buffer)) != -1) {
                // Convert to String so we can display it.
                // Of course you wouldn't want to do this with
                // a 'real' binary file.
                System.out.println(new String(buffer));
                total += nRead;
            }   

            // Always close files.
            inputStream.close();        

            System.out.println("Read " + total + " bytes");
        }
        catch(FileNotFoundException ex) {
            System.out.println(
                "Unable to open file '" + 
                fileName + "'");                
        }
        catch(IOException ex) {
            System.out.println(
                "Error reading file '" 
                + fileName + "'");                  
            // Or we could just do this: 
            // ex.printStackTrace();
        }
    }

    private void fileReadThree() {
        String content = null;
           File file = new File("G:testFile.txt"); //for ex foo.txt
           FileReader reader = null;
           try {
               reader = new FileReader(file);
               char[] chars = new char[(int) file.length()];
               reader.read(chars);
               content = new String(chars);
               System.out.println(content);
           } catch (IOException e) {
               e.printStackTrace();
           } finally {
               try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
           }
    }

    private void fileReadFour() {
       File f = new File("G:testFile.txt");
            String text = "";
            int read, N = 1024 * 1024;
            char[] buffer = new char[N];

            try {
                FileReader fr = new FileReader(f);
                BufferedReader br = new BufferedReader(fr);

                while(true) {
                    read = br.read(buffer, 0, N);
                    text += new String(buffer, 0, read);

                    if(read < N) {
                        break;
                    }
                }
            } catch(Exception ex) {
                ex.printStackTrace();
            }
           System.out.println(text);
        }

    //Doesn't keep file formatting
    private void fileReadfive() {
          Scanner s = null;
            try {
                try {
                    s = new Scanner(new BufferedReader(new FileReader("G:testFile.txt")));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                    while (s.hasNext()) {
                        System.out.println(s.next());
                    }
            } finally {
                if (s != null) {
                    s.close();
                }
            }
    }

    private void fileReadSumsTheFileOfNumbersScanner() {
        Scanner s = null;
        double sum = 0;

        try {
            try {
                s = new Scanner(new BufferedReader(new FileReader("G:n.txt")));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            s.useLocale(Locale.US);

            while (s.hasNext()) {
                if (s.hasNextDouble()) {
                    sum += s.nextDouble();
                } else {
                    s.next();
                }   
            }
        } finally {
            s.close();
        }
        System.out.println(sum);
    }

    private void fileWriterOneTextFile() {
        String fileName = "G:testTemp.txt";
        try {
            // Assume default encoding.
            /*
             Whether or not a file is available or may be created depends upon the underlying platform. Some platforms, in particular, 
             allow a file to be opened for writing by only one FileWriter (or other file-writing object) at a time. In such 
             situations the constructors in this class will fail if the file involved is already open. 
             FileWriter is meant for writing streams of characters. For writing streams of raw bytes, consider using a 
             FileOutputStream.
             */
            FileWriter fWriter = new FileWriter(fileName);
            // Always wrap FileWriter in BufferedWriter.
            /*
             The buffer size may be specified, or the default size may be accepted. The default is large enough for most purposes.
             A newLine() method is provided, which uses the platform's own notion of line separator as defined by the system 
             property line.separator. Not all platforms use the newline character ('\n') to terminate lines. Calling this method 
             to terminate each output line is therefore preferred to writing a newline character directly. 
             In general, a Writer sends its output immediately to the underlying character or byte stream. Unless prompt output 
             is required, it is advisable to wrap a BufferedWriter around any Writer whose write() operations may be costly, such as 
             FileWriters and OutputStreamWriters. For example, 
                PrintWriter out
                    = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
             will buffer the PrintWriter's output to the file. Without buffering, each invocation of a print() method would cause 
             characters to be converted into bytes that would then be written immediately to the file, which can be very inefficient.
             */
            BufferedWriter bW = new BufferedWriter(fWriter);
            // Note that write() does not automatically
            // append a newline character.
            bW.write("This is a test string that will be written to the file!!!!");
            bW.write("This more text that will be written to the file!!!!");
            bW.newLine();
            bW.write("After the newLine bufferedWriter method.");
            bW.write(" A   B   C D E         F     G");
            bW.newLine();
            bW.write("Hauf");
            bW.close();
        } catch(IOException ex) {
            System.out.println("Error writing to file '" + fileName + "'");
            ex.printStackTrace();
        }
    }

     List<String> readSmallTextFile(String aFileName) throws IOException {
            Path path = Paths.get(aFileName);
            return Files.readAllLines(path, ENCODING);
          }

          void writeSmallTextFile(List<String> aLines, String aFileName) throws IOException {
            Path path = Paths.get(aFileName);
            Files.write(path, aLines, ENCODING);
          }

          //For larger files
          void readLargerTextFile(String aFileName) throws IOException {
            Path path = Paths.get(aFileName);
            try (Scanner scanner =  new Scanner(path, ENCODING.name())){
              while (scanner.hasNextLine()){
                //process each line in some way
                log(scanner.nextLine());
              }      
            }
          }

          void readLargerTextFileAlternate(String aFileName) throws IOException {
            Path path = Paths.get(aFileName);
            try (BufferedReader reader = Files.newBufferedReader(path, ENCODING)){
              String line = null;
              while ((line = reader.readLine()) != null) {
                //process each line in some way
                log(line);
              }      
            }
          }

          void writeLargerTextFile(String aFileName, List<String> aLines) throws IOException {
            Path path = Paths.get(aFileName);
            try (BufferedWriter writer = Files.newBufferedWriter(path, ENCODING)){
              for(String line : aLines){
                writer.write(line);
                writer.newLine();
              }
            }
          }

          private static void log(Object aMsg){
            System.out.println(String.valueOf(aMsg));
          }

    public static void main(String[] args) throws IOException {
        DDHExampleTextFileReader doug = new DDHExampleTextFileReader();
        List<String> lines = doug.readSmallTextFile(FILE_NAME);
        //doug.fileReadOne();
        //doug.fileReadTwo();
        //doug.fileReadThree();
        //doug.fileReadFour();
        //doug.fileReadfive();
        //doug.fileReadSumsTheFileOfNumbersScanner();
        doug.fileWriterOneTextFile();
        log(lines);
            lines.add("This is a line added in code.");
            doug.writeSmallTextFile(lines, FILE_NAME);

            doug.readLargerTextFile(FILE_NAME);
            lines = Arrays.asList("Down to the Waterline", "Water of Love");
            doug.writeLargerTextFile(OUTPUT_FILE_NAME, lines);



        System.out.println(String.valueOf("\n\n\n-----End of Main Method!!!------"));
    }
}


/*
public static void copy(Reader input, OutputStream output, String encoding)
                   throws IOException {
               if (encoding == null) {
                    copy(input, output);
                } else {
                    OutputStreamWriter out = new OutputStreamWriter(output, encoding);
                    copy(input, out);
                    // XXX Unless anyone is planning on rewriting OutputStreamWriter,
                    // we have to flush here.
                    out.flush();
                }
     }

    public static void copy(Reader input, OutputStream output)
                    throws IOException {
                OutputStreamWriter out = new OutputStreamWriter(output);
                copy(input, out);
                // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
                // have to flush here.
                out.flush();
     }

     public static int copy(Reader input, Writer output) throws IOException {
                  //  long count = copyLarge(input, output);
                    //copy large
                    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
                    long count = 0;
                    int n = 0;
                    while (-1 != (n = input.read())) {
                        output.write(0);
                        count += n;
                    }

                    //end copy large
                    if (count > Integer.MAX_VALUE) {
                        return -1;
                    }
                    return (int) count;
    }

    public static long copyLarge(InputStream i, OutputStream o) throws IOException {
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            long count = 0;
            int n = 0;
            while (-1 != (n = i.read(buffer))) {
              o.write(buffer, 0, n);
              count += n;
            }
        return count;
    }

    public static String toString(InputStream input) throws IOException {
                    StringWriter sw = new StringWriter();
                     copy(input, sw);
                     return sw.toString();
    }

    public static void copy(InputStream input, Writer output) throws IOException {
              InputStreamReader in = new InputStreamReader(input);
          copy(in, output);
    }


    public static void copy(InputStream input, Writer output, String encoding) throws IOException {
                if (encoding == null) {
                    copy(input, output);
                } else {
                    InputStreamReader in = new InputStreamReader(input, encoding);
                    copy(in, output);
                }
     }

最佳答案

My question here is why does the FileWriter variable need to be wrapped in a BufferedWriter.

它不是必须 - 但如果这样做,您可能会获得更好的性能,从而避免经常访问磁盘。

此外,您正在使用 BufferedWriter.newLine ,未为 FileWriter 定义- 不过,手动编写新行会很容易。

我建议您使用 FileOutputStream包裹在 OutputStreamWriter 中, 而不是使用 FileWriter直接 - 这样您就可以指定应该使用的编码,而不仅仅是使用平台默认编码。

我还建议避免 PrintWriter因为它会吞下异常 - IMO,这不是一个好主意。

关于Java——缓冲读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20271873/

相关文章:

java - 使用 c 调用 REST 服务,通过 GSM 调制解调器连接 - HTTP/1.1 505

java - 如何在另一种方法中使用来自一种方法的用户输入字符串?

java - JPA Criteria API 检查关联集合是否是另一个集合的子集

java - 使用 Spring Data JPA 从 1 个表中按列查找并从另一个表中按列排序

java - 有没有办法同时对项目的所有文件执行 'Save Actions' ?

java - getStringArrayListExtra 给我一个空值,但我有值

java - Netbeans选择问题?

java - 如何从ArrayList中删除随机元素

java - 在运行时从数组列表中添加和删除用户并保留项目详细信息

java - 将数据非线性解析为不可变对象(immutable对象)