我无法真正理解Java中的类FileReader和目的是什么BufferedReader.
在docs.oracle,建议将一个缓冲读取器包装在一个FileReader对象周围,因为FileReader直接使用它是没有效率的.成本或间接费用来自哪里?
假设我有一个文本文件,我想用这些类读入我的java程序:
我使用FileReader和BufferedReader
FileReader fileReader = new FileReader(new File("text.txt)"); // probably correct???
BufferedReader bufferedReader = new BufferedReader(fileReader);
Run Code Online (Sandbox Code Playgroud)
1)FileReader这里对象的任务是什么?是否负责通过操作系统向文件发出I/O请求,然后读取字节?这有什么代价?FileReader提出几个I/O请求是真的吗?或者是FileReader对象必须逐字符地将字节转换为字符的成本?
2)BufferedReader-object的任务 - 引用上面的最后一句话. - BufferedReader对象的角色是简单地缓冲传入字节的数组,然后将它们转换为字符?
非常感谢答案
编辑:首先感谢收到的答案.但我应该提到它正是我研究过的文档.叫我愚蠢或什么 - 但"每个阅读请求"是什么意思.什么时候每个读取请求?多常?
通常,由Reader构成的每个读取请求都会导致相应的读取请求由基础字符或字节流构成.因此,建议将BufferedReader包装在任何read()操作可能代价高昂的Reader上,例如FileReaders和InputStreamReaders.例如,
这主要是为什么推出这个问题 - 听起来FileReader会导致很多I/O请求,这会减慢错误.
所有,
我试图确保在捕获IOException时关闭了我用BufferedReader打开的文件,但看起来好像我的BufferedReader对象超出了catch块的范围.
public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
fileArrayList.removeAll(fileArrayList);
try {
//open the file for reading
BufferedReader fileIn = new BufferedReader(new FileReader(fileName));
// add line by line to array list, until end of file is reached
// when buffered reader returns null (todo).
while(true){
fileArrayList.add(fileIn.readLine());
}
}catch(IOException e){
fileArrayList.removeAll(fileArrayList);
fileIn.close();
return fileArrayList; //returned empty. Dealt with in calling code.
}
}
Run Code Online (Sandbox Code Playgroud)
Netbeans抱怨它在catch块中"找不到符号fileIn",但是我想确保在IOException的情况下Reader被关闭.如果没有第一次尝试/捕获构造的丑陋,我怎么能这样做呢?
关于这种情况下的最佳实践的任何提示或指示表示赞赏,
java exception-handling try-catch ioexception bufferedreader
我想发一个HTTP请求,然后按照草图在这里得到响应:
URLConnection c = new URL("http://foo.com").openConnection();
c.setDoOutput(true);
/* write an http request here using a new OutputStreamWriter(c.getOutputStream) */
BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream));
reader.readLine();
Run Code Online (Sandbox Code Playgroud)
但我的问题是,如果我发送的请求需要很长时间才能收到响应,那么上面的调用reader.readLine()会发生什么?此进程是否会在CPU上保持运行/可运行,还是会从CPU中取出并在有IO被读取时被通知唤醒并再次运行?
如果它停留在CPU上,可以做些什么让它下来并在以后得到通知?
我以前从未接触过Java IO API的经验,现在我真的很沮丧.我发现很难相信它有多奇怪和复杂,做一个简单的任务有多难.
我的任务:我有2个位置(起始字节,结束字节),pos1和pos2.我需要读取这两个字节之间的行(包括起始字节,不包括结尾字节),并将它们用作UTF8字符串对象.
例如,在大多数脚本语言中,它将是一个非常简单的1-2-3-liner(在Ruby中,但它对于Python,Perl等基本相同):
f = File.open("file.txt").seek(pos1)
while f.pos < pos2 {
s = f.readline
# do something with "s" here
}
Run Code Online (Sandbox Code Playgroud)
使用Java IO API很快就会出现问题;)实际上,我看到了两种\n从常规本地文件中读取行(以...结尾)的方法:
getFilePointer()和seek(long pos),但它的readLine()读取非UTF8字符串(甚至不是字节数组),但非常奇怪的字符串具有破坏的编码,并且它没有缓冲(这可能意味着每个read*()调用都将被转换为单个不连续的OS read()= >相当慢).readLine()方法,它甚至可以进行一些搜索skip(long n),但它无法确定已经读取的偶数字节数,也没有提到文件中的当前位置.我试过用类似的东西:
FileInputStream fis = new FileInputStream(fileName);
FileChannel fc = fis.getChannel();
BufferedReader br = new BufferedReader(
new InputStreamReader(
fis,
CHARSET_UTF8
)
);
Run Code Online (Sandbox Code Playgroud)
...然后使用fc.position()获取当前文件读取位置并fc.position(newPosition)设置一个,但它似乎在我的情况下不起作用:看起来它返回由BufferedReader完成的缓冲区预填充的位置,或类似的东西 - …
我正在用java编写一个小应用程序
我读了各种大小的文本文件,我需要逐行读取它们(并将行插入数组).
是否有差异BufferedReader.ReadLine(),并RandomAccessFile.ReadLine()在性能方面?
有没有理由更喜欢其中一个?
我有8个文件.它们中的每一个大约是1.7 GB.我正在将这些文件读入字节数组,并且该操作足够快.
然后读取每个文件如下:
BufferedReader br=new BufferedReader(new InputStreamReader(new ByteArrayInputStream(data)));
Run Code Online (Sandbox Code Playgroud)
当使用单个核心按顺序处理时,需要花费60秒才能完成.但是,当在8个单独的核心上分配计算时,每个文件花费的时间远远超过60秒.
由于数据都在内存中并且没有执行IO操作,因此我认为每个核处理一个文件所需的时间不应超过60秒.因此,总共8个文件应该在60秒内完成,但事实并非如此.
我错过了一些关于BufferedReader行为的内容吗?或上述代码中使用的任何读者.
值得一提的是,我正在使用此代码首先上传文件:
byte[] content=org.apache.commons.io.FileUtils.readFileToByteArray(new File(filePath));
Run Code Online (Sandbox Code Playgroud)
所有代码看起来像这样:
For each file
read the file into a byte[]
add the byte[] to a list
end For
For each item in the list
create a thread and pass a byte[] to it
end For
Run Code Online (Sandbox Code Playgroud) 我试图使用以下代码从IHTTPSession.getInputStream()读取InputStream,但每次都给出Socket TimeOut异常.
private String readInStream(InputStream in){
StringBuffer outBuffer=new StringBuffer();
BufferedInputStream bis=new BufferedInputStream(in);
try {
while(bis.available()>0){
int ch= bis.read();
outBuffer.append((char)ch);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("DATA_Length", "outputBuffer :"+outBuffer.toString().length());
return outBuffer.toString();
}
Run Code Online (Sandbox Code Playgroud)
我也尝试了以下方法,但出现了同样的异常
private String readInStream(InputStream in){
String line="";
StringBuffer outBuffer=new StringBuffer();
BufferedReader rd=new BufferedReader(new InputStreamReader(in));
try {
while((line=rd.readLine()) != null){
outBuffer.append(line);
}
} catch (IOException e) {
Log.e("IOException", "IOException in readInStream:");
e.printStackTrace();
}
Log.e("DATA_Length", "outputBuffer :"+outBuffer.toString().length());
return outBuffer.toString();
}
Run Code Online (Sandbox Code Playgroud) 问题 一个简单的编程问题,涉及从控制台读取N,T次数并对其执行简单计算.
约束:
1≤T≤1000
2≤N≤100000000
由于BufferedReader通常比Scanner快,我使用它但程序退出非零退出代码,而使用Scanner解决了问题.
由于两者在我的计算机上都能正常工作,我怀疑这是一个内存问题.
问题:
码:
使用BufferedReader,抛出错误
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int i=0; i<T; i++) {
int N = Integer.parseInt(br.readLine());
int res = (N/2)+1;
System.out.println(res);
}
br.close();
}
}
Run Code Online (Sandbox Code Playgroud)
使用Scanner返回正确输出的代码:
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException{
Scanner sc = new …Run Code Online (Sandbox Code Playgroud) 对于在学校的作业我被要求创建一个简单的程序,创建1000个文本文件,每个文件具有随机数量的行,通过多线程\单个进程计算有多少行.而不是删除那些文件.
现在测试过程中发生了一件奇怪的事情 - 所有文件的线性计数总是比以多线程方式计算它们要快一点,这已经激发了我课堂圈内的学术理论化课程.
当Scanner用于读取所有文件时,一切都按预期工作 - 在500毫秒线性时间和400毫秒线程时间读取1000个文件
然而,当我使用BufferedReader时间下降到大约110ms线性和130ms线程.
哪部分代码会导致这个瓶颈?为什么?
编辑:只是为了澄清,我不是问为什么Scanner工作慢于BufferedReader.
完整的可编译代码:(虽然你应该改变文件创建路径输出)
import java.io.*;
import java.util.Random;
import java.util.Scanner;
/**
* Builds text files with random amount of lines and counts them with
* one process or multi-threading.
* @author Hazir
*/// CLASS MATALA_4A START:
public class Matala_4A {
/* Finals: */
private static final String MSG = "Hello World";
/* Privates: */
private static int count;
private static Random rand;
/* Private Methods: …Run Code Online (Sandbox Code Playgroud) 我有一些来自不同文件的数据流。它的格式如下:
Stream<String> linesModifiedAndAppendedFromVariousFiles=getLines();
Run Code Online (Sandbox Code Playgroud)
但是,我需要将其提供给接受 InputStream 或 Reader 作为参数的库方法。
如何将此 Java 8 流馈送到 InputStream 或某种类型的 Reader 中?
PS:这不是关于将 java.util.streams.Stream 包装在 InputStream 周围。我正在寻找的是相反的方式。
bufferedreader ×10
java ×9
inputstream ×2
blocking ×1
file ×1
file-io ×1
filereader ×1
io ×1
ioexception ×1
multicore ×1
nanohttpd ×1
networking ×1
nio ×1
overhead ×1
readline ×1
stream ×1
try-catch ×1