我想使用BufferedReader在控制台中输入多行文本,当我点击"Enter"以查找整个文本长度的总和时.问题是,我似乎进入了一个无限循环,当我按下"Enter"时,程序没有结束.我的代码如下:
InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);
line= buffer.readLine();
while (line!=null){
length = length + line.length();
line= buffer.readLine();
}
Run Code Online (Sandbox Code Playgroud)
你能告诉我我做错了什么吗?
我正在从一个文件中读取数据,遗憾的是,这种文件有两种类型的字符编码.
有一个标题和一个正文.标头始终为ASCII,并定义正文编码的字符集.
标头不是固定长度,必须通过解析器运行以确定其内容/长度.
该文件也可能非常大,所以我需要避免将整个内容带入内存.
所以我开始使用单个InputStream.我最初使用带有ASCII的InputStreamReader包装它并解码标头并提取主体的字符集.都好.
然后我创建一个具有正确字符集的新InputStreamReader,将其放在同一个InputStream上并开始尝试读取正文.
不幸的是,javadoc证实了这一点,即InputStreamReader可能会选择提前读取以达到效率目的.因此,标题的阅读会咀嚼身体的一部分/全部.
有没有人有解决这个问题的建议?会手动创建一个CharsetDecoder并一次输入一个字节但是一个好主意(可能包含在自定义的Reader实现中吗?)
提前致谢.
编辑:我的最终解决方案是编写一个没有缓冲的InputStreamReader,以确保我可以解析标题而不会咀嚼身体的一部分.虽然这不是非常有效,但我使用BufferedInputStream包装原始InputStream,因此它不会成为问题.
// An InputStreamReader that only consumes as many bytes as is necessary
// It does not do any read-ahead.
public class InputStreamReaderUnbuffered extends Reader
{
private final CharsetDecoder charsetDecoder;
private final InputStream inputStream;
private final ByteBuffer byteBuffer = ByteBuffer.allocate( 1 );
public InputStreamReaderUnbuffered( InputStream inputStream, Charset charset )
{
this.inputStream = inputStream;
charsetDecoder = charset.newDecoder();
}
@Override
public int read() throws IOException
{
boolean middleOfReading = false;
while ( true …Run Code Online (Sandbox Code Playgroud) 这段代码正在创建BufferedReader和InputStreamReader导致的内存泄漏问题,我认为可能会发生一些异常.我该怎么改变它?
try{
URL url = new URL(sMyUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
while ((str = in.readLine()) != null) {
jsonString += str;
}
in.close();
}catch(Exception e){
}
Run Code Online (Sandbox Code Playgroud) 我在数据库中有一些CLOB列,我需要将Base64编码的二进制文件放入.这些文件可能很大,所以我需要流式传输它们,我无法立即读取整个内容.
我正在使用org.apache.commons.codec.binary.Base64InputStream编码,我遇到了问题.我的代码基本上就是这个
FileInputStream fis = new FileInputStream(file);
Base64InputStream b64is = new Base64InputStream(fis, true, -1, null);
BufferedReader reader = new BufferedReader(new InputStreamReader(b64is));
preparedStatement.setCharacterStream(1, reader);
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,我在执行更新期间得到其中一个代码,
java.io.IOException: Underlying input stream returned zero bytes它在InputStreamReader代码中被深深抛出.
为什么这不起作用?在我看来,它reader会尝试从基本的64流中读取,这将从文件流中读取,并且一切都应该是快乐的.
我试图从二进制流中读取数据,其中一部分应该被解析为UTF-8.
InputStream直接使用二进制数据并InputStreamReader在其上面使用UTF-8文本不起作用,因为读者将提前读取并弄乱后续二进制数据,即使它被告知读取最多n字符.
我认识到这个问题非常类似于从多种格式的InputStream读取,但是提出的解决方案特定于HTTP流,这对我没有帮助.
我想把所有东西都读成二进制数据,然后将相关的部分转换成文本.但我只有字符数据的长度信息,而不是字节.因此,我需要从流中读取字符的东西才能知道编码.
有没有办法告诉InputStreamReader不要读取比读取给定数量的字符所需的更多?或者是否有一个支持二进制数据和带编码的文本的阅读器,可以在这些模式之间切换?
我有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) 我有一些字节应该是UTF-8编码,但其中可能包含文本是ISO8859-1编码,如果用户以某种方式没有设法使用他的文本编辑器正确的方式.
我用InputStreamReader读取文件:
InputStreamReader reader = new InputStreamReader(
new FileInputStream(file), Charset.forName("UTF-8"));
Run Code Online (Sandbox Code Playgroud)
但是每次用户使用像ä"这样的变音符号时,如果存储在ISO8859-1中是无效的UTF-8,则InputStreamReader不会抱怨但会添加占位符字符.
是否有简单的方法使这个无效输入抛出异常?
正如我暂时理解它:
DataInputStream是一个InputStream子类,因此它读取和写入字节.如果您正在读取字节,并且您知道它们将是ints或其他一些原始数据类型,那么您可以byte使用它直接读取它们DataInputStream.
我遇到的问题是:为什么不使用InputStreamReader缠绕InputStream的字节数据?使用这种方法,您仍然在读取字节,然后将它们转换为表示字符的整数.哪个整数表示哪些字符取决于指定的字符集,例如"UTF-8".
InputStreamReader工作无效DataInputStream?我的猜测答案:如果速度真的很重要,你可以做到,那么将InputStream字节数据直接转换为原始数据DataInputStream将是要走的路?这避免了Reader必须将字节数据"转换"为int第一个; 并且它不依赖于提供一个字符集来解释返回的整数表示哪个字符.我想这就是人们的意思,DataInputStream允许机器独立读取底层数据.
DataInputStream可以将字节直接转换为基元.引发整个事情的问题:我正在阅读以下教程代码:
FileInputStream fis = openFileInput("myFileText");
BufferedReader reader = new BufferedReader( new InputStreamReader( new DataInputStream(fis)));
EditText editText = (EditText)findViewById(R.id.edit_text);
String line;
while( (line = reader.readline()) != null){
editText.append(line);
editText.append("\n");
}
Run Code Online (Sandbox Code Playgroud)
...我不明白教师为什么选择使用new DataInputStream(fis)它,因为它看起来不像直接从字节转换为基元的任何能力正在被利用?
感谢您的见解.
我想ping一个目标IP地址并收到响应.为了实现这一点,我在Java中使用了带有runtime.exec方法和进程类的Windows命令行.我正在使用inputStreamReader获取响应.
我的默认字符集是windows-1254,它是土耳其语.当我收到它时,响应包含土耳其语字符,但在控制台中没有正确显示土耳其语字符.
我想从我得到的响应中获取一个数值,但我搜索的值包含一些土耳其字符,所以当我查找它时,我找不到它.
代码如下,我需要知道的是如何在这里看到土耳其字符:
runtime = Runtime.getRuntime();
process = runtime.exec(pingCommand);
BufferedReader bReader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "UTF8"));
String inputLine;
while ((inputLine = bReader.readLine()) != null) {
pingResult += inputLine;
}
bReader.close();
process.destroy();
System.out.println(pingResult);
Run Code Online (Sandbox Code Playgroud) 我正在学习Android开发(我是一般的编程初学者)并学习HTTP网络,并在课程中看到了这段代码:
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
Run Code Online (Sandbox Code Playgroud)
我不完全理解InputStream,InputStreamReader和BufferedReader的作用.所有这些都有一个read()方法,并且在BufferedReader的情况下也有readLine().为什么我不能只使用InputStream或只添加InputStreamReader?为什么我需要添加BufferedReader?我知道这与效率有关,但我不明白如何.
我一直在研究,BufferedReader的文档试图解释这个,但我仍然不知道谁在做什么:
通常,由Reader构成的每个读取请求都会导致相应的读取请求由基础字符或字节流构成.因此,建议将BufferedReader包装在任何read()操作可能代价高昂的Reader上,例如FileReaders和InputStreamReaders.例如,
BufferedReader in = new BufferedReader(new FileReader("foo.in"));将缓冲指定文件的输入.如果没有缓冲,read()或readLine()的每次调用都可能导致从文件中读取字节,转换为字符,然后返回,这可能是非常低效的.
所以,据我所知,InputStream只能读取一个字节,InputStreamReader只能读取一个字符,而BufferedReader只能读取整行,并且它还可以解决效率问题,这是我无法得到的.我想更好地了解谁在做什么,以便理解为什么我需要他们所有这三个以及没有他们之一的差别.
我在这里和网上的其他地方进行了很多研究,似乎没有找到任何关于我可以理解的解释,几乎所有教程都只重复文档信息.以下是一些相关的问题,可能会开始解释这一点,但不要深入解决我的困惑:Q1,Q2,Q3,Q4.我认为这可能与最后一个问题关于系统调用和返回的解释有关.但我想了解这一切的含义.
可能是BufferedReader的readLine()调用了InputStreamReader的read()方法,而该方法又调用了InputStream的read()方法?并且InputStream返回转换为int的字节,一次返回一个字节,InputStreamReader读取足够的这些字符以生成单个字符并将其转换为int并一次返回一个字符,并且BufferedReader读取足够的这些字符用整数表示整数?并将整行作为String返回,只返回一次而不是几次?我不知道,我只是想弄清楚事情是如何运作的.
非常感谢提前!