Java input.read和input.read之间的差异(数组、偏移量、长度)

Java input.read和input.read之间的差异(数组、偏移量、长度),java,bufferedinputstream,Java,Bufferedinputstream,我试图了解输入流是如何工作的。以下代码块是从文本文件读取数据的多种方法之一:- File file = new File("./src/test.txt"); InputStream input = new BufferedInputStream (new FileInputStream(file)); int data = 0; while (data != -1) (-1 means we reached the end of the file) { data = inpu

我试图了解输入流是如何工作的。以下代码块是从文本文件读取数据的多种方法之一:-

File file = new File("./src/test.txt");
InputStream input = new BufferedInputStream (new FileInputStream(file));
int data = 0;

while (data != -1)   (-1 means we reached the end of the file)
 {
     data = input.read(); //if a character was read, it'll be turned to a bite and we get the integer representation of it so a is 97 b is 98
     System.out.println(data + (char)data); //this will print the numbers followed by space then the character
 }

input.close();
现在使用
input.read(字节、偏移量、长度)
我有这个代码。我是从你那儿得到的

File File=new文件(“./src/test.txt”);
InputStream输入=新的BufferedInputStream(新文件InputStream(文件));
int totalBytesRead=0,字节剩余,字节读取;
字节[]结果=新字节[(int)file.length()];
while(totalBytesRead0)
totalBytesRead=totalBytesRead+bytesRead;
//打印读取的字节的整数版本
for(int i=0;i
我假设基于名称
BYTESREAD
,此读取方法返回读取的字节数。在文档中,它表示函数将尝试读取尽可能多的内容。所以可能有一个原因它不会

我的第一个问题是:这些原因是什么?

我可以用一行代码替换整个while循环:
input.read(result,0,result.length)


我相信这篇文章的作者已经考虑过了。这与输出无关,因为我在两种情况下都得到相同的输出。所以一定有原因。至少有一个。它是什么?

您指定要读取的字节数,因为您可能不想一次读取整个文件,或者可能无法或不想创建与文件一样大的缓冲区。

说明:

  • 读取最多为len字节的数据
  • 尝试读取多达个字节
  • 可以读取较小的数字
由于我们使用的是硬盘中的文件,因此可以合理地预期尝试将读取整个文件,但是
input.read(result,0,result.length)
不能保证读取整个文件(文档中没有提到)。当未记录的行为发生变化时,依赖未记录的行为是bug的来源

例如,文件流可能在其他JVM中以不同的方式实现,一些操作系统可能会对您一次可以读取的字节数施加限制,文件可能位于网络中,或者您可能稍后将该代码段用于流的另一个实现,而流的另一个实现不会以这种方式运行

或者,如果您正在读取数组中的整个文件,您可以使用


关于带有
read()
的循环,它每次读取一个字节。如果您正在读取一大块数据,这会降低性能,因为每次调用
read()
都会执行多个测试(流是否已结束?等等),并可能要求操作系统提供一个字节。既然您已经知道需要
file.length()
字节,那么就没有理由不使用其他更高效的表单。

想象一下,您是从网络套接字而不是从文件中读取的。在这种情况下,您没有关于流中字节总数的任何信息。您将分配一个固定大小的缓冲区,并在循环中从流中读取。在循环的一次迭代中,您不能期望流中有可用的BUFFERSIZE字节。因此,您将尽可能多地填充缓冲区,然后再次迭代,直到缓冲区已满。如果您有固定大小的数据块,例如序列化对象,这可能很有用

ArrayList<MyObject> list = new ArrayList<MyObject>();

try {

    InputStream input = socket.getInputStream();
    byte[] buffer = new byte[1024];

    int bytesRead;
    int off = 0;
    int len = 1024;

    while(true) {
        bytesRead = input.read(buffer, off, len);            

        if(bytesRead == len) {
                list.add(createMyObject(buffer));
                // reset variables
                off = 0;
                len = 1024;
                continue;
        }

        if(bytesRead == -1) break;

        // buffer is not full, adjust size
        off += bytesRead;
        len -= bytesRead;
    }

} catch(IOException io) {
    // stream was closed
}
ArrayList list=new ArrayList();
试一试{
InputStream输入=socket.getInputStream();
字节[]缓冲区=新字节[1024];
int字节读取;
int off=0;
int len=1024;
while(true){
bytesRead=输入读取(缓冲区、关闭、len);
if(字节读==len){
添加(CreateMObject(缓冲区));
//重置变量
关=0;
len=1024;
继续;
}
如果(字节读==-1)中断;
//缓冲区未满,请调整大小
off+=字节读取;
len-=字节读取;
}
}捕获(io异常){
//溪流关闭了
}

ps.代码未经测试,只需指出此功能的用途。

简短回答?您可能试图读取20个字节,但只剩下10个字节。由于这些原因,thanx非常多。我突然想到我可以直接使用BufferedReader。如果我使用BufferedReader,我相信您提到的原因(网络、实现、操作系统等)将不适用。但请在你写的最后一段详细说明。你是说因为我想读取整个文件,所以不需要循环吗?在最后一段中,我指出了
read()
read(byte[],int,int)
之间的区别,因为你在问题中发布了这两个代码。我对第三方图书馆的非法行为没有信心,因为某天/某地事情可能会破裂,节省几行代码的代价太高了。(当然,如果您正在编写一个快速的示例,您可以玩这些把戏,但在实际的生产代码中尽量避免这些把戏)。我添加了对DataInputStream的引用,它将整个流读取到字节数组中。我想在特定点插入unicode控制字符。prb是所有读取方法都给我一个固定大小的数组,所以我不能扩展它。我唯一的选择是使用input.read(),它将返回我读取的字节。但是你说阅读会减慢我的表现。那我该怎么办?一旦你读到我的应用程序的目的,你就会意识到你的Readfull不会工作。顺便问一下,dif是什么
ArrayList<MyObject> list = new ArrayList<MyObject>();

try {

    InputStream input = socket.getInputStream();
    byte[] buffer = new byte[1024];

    int bytesRead;
    int off = 0;
    int len = 1024;

    while(true) {
        bytesRead = input.read(buffer, off, len);            

        if(bytesRead == len) {
                list.add(createMyObject(buffer));
                // reset variables
                off = 0;
                len = 1024;
                continue;
        }

        if(bytesRead == -1) break;

        // buffer is not full, adjust size
        off += bytesRead;
        len -= bytesRead;
    }

} catch(IOException io) {
    // stream was closed
}