我正在为自己编写一个程序,它展示了在文本文件中读取的所有不同方式。我用过FileWriter和BufferedWriter。
我在这里的问题是,为什么需要将FileWriter变量包装在BufferedWriter中。我在代码中看到了很多这种情况,在某些情况下,比如在Integer中包装的int。这对我来说是有意义的,但是在BufferedWriter中包装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);
}
}发布于 2013-11-28 17:40:21
如您所知,缓冲区是用于存储正在处理的数据的临时内存位置。在BufferedWriter和BufferedReader的情况下,您正在使用它来减少写入或读取硬盘驱动器的次数。
想想超市里发生了什么。你坐一辆手推车,走在货架上,把你的手推车装满货物。这样做的目的是到收银台去一趟。假设你一次只买一件东西,而不用手推车呢?你要花很长时间才能买到食品杂货。
当您要求BufferedWriter向文件写入一些字节时,它实际上只是将其存储在缓冲区中。当缓冲区满了,或者您刷新它时,缓冲区中的所有内容都是用一次写入文件系统的方式编写的。
Java框架使用装饰设计模式。这意味着您可以在运行时构造适合您需要的作者或读者。因此,如果您需要一个缓冲的读取器,那么可以使用任何一个读取器,并将其包装在缓冲的读取器中。如果您需要其他一些功能,那么使用适当的包装器来简单地添加所需的功能。
输入或输出的核心是一个名为InputStream或OutputStream的类。让我们以InputStream为例。InputStream只读取字节。例如,read()方法可以读取单个字节,或者读取(byte[] b)可以读取字节数组。对于非常低级别的输入,这是一个有用的类。但是,每次调用read()时,它都必须从硬盘中提取一个字节,这个字节可能非常慢。因此,在需要从文件中读取许多字节的情况下,可以将InputStream封装在BufferedStream中,并获得缓冲区的好处。
InputStreamReader类是连接字节到字符的InputStream的包装器。InputStreamReader的read()方法读取单个字符。FileReader类是InputStreamReader的包装器,它添加了从文件中读取的功能。
因此,当您在java.io中浏览一组类时,您会看到每个类都添加了一些功能,您可以将各种对象包装在您想要的任何一层功能中。
发布于 2013-11-28 17:35:19
我在这里的问题是,为什么需要将FileWriter变量包装在BufferedWriter中。
这不是必须的--但是如果这样做,您很可能会获得更好的性能,这样您就可以避免经常去磁盘。
另外,您使用的是BufferedWriter.newLine,它不是为FileWriter定义的--尽管手动编写新行很容易。
我建议您使用包装在OutputStreamWriter中的OutputStreamWriter,而不是直接使用FileWriter --这样您就可以指定应该使用哪种编码,而不仅仅是使用平台默认编码。
我还建议避开PrintWriter,因为它会吞噬例外--这不是个好主意,IMO。
https://stackoverflow.com/questions/20271873
复制相似问题