Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从本地文件读取InputStream对象与从网络(通过AmazonS3)读取InputStream对象有何不同?_Java_File_Amazon S3_Inputstream_Local - Fatal编程技术网

Java 从本地文件读取InputStream对象与从网络(通过AmazonS3)读取InputStream对象有何不同?

Java 从本地文件读取InputStream对象与从网络(通过AmazonS3)读取InputStream对象有何不同?,java,file,amazon-s3,inputstream,local,Java,File,Amazon S3,Inputstream,Local,我不认为从本地文件读取的inputstream对象和从网络源读取的inputstream对象(本例中为AmazonS3)之间有什么区别,所以希望有人能给我一些启发 这些程序在运行Centos 6.3的虚拟机上运行。 两种情况下的测试文件都是10MB 本地文件代码: InputStream is = new FileInputStream("/home/anyuser/test.jpg"); int read = 0; int buf_size = 1024 * 1024

我不认为从本地文件读取的inputstream对象和从网络源读取的inputstream对象(本例中为AmazonS3)之间有什么区别,所以希望有人能给我一些启发

这些程序在运行Centos 6.3的虚拟机上运行。 两种情况下的测试文件都是10MB

本地文件代码:

    InputStream is = new FileInputStream("/home/anyuser/test.jpg");

    int read = 0;
    int buf_size = 1024 * 1024 * 2;
    byte[] buf = new byte[buf_size];

    ByteArrayOutputStream baos = new ByteArrayOutputStream(buf_size);

    long t3 = System.currentTimeMillis();
    int i = 0;
    while ((read = is.read(buf)) != -1) {
        baos.write(buf,0,read);
        System.out.println("reading for the " + i + "th time");
        i++;
    }
    long t4 = System.currentTimeMillis();
    System.out.println("Time to read = " + (t4-t3) + "ms");
这段代码的输出是这样的:它读取了5次,这是有意义的,因为读取的缓冲区大小是2MB,文件是10MB

reading for the 0th time
reading for the 1th time
reading for the 2th time
reading for the 3th time
reading for the 4th time
Time to read = 103ms
现在,我们使用相同的10MB测试文件运行相同的代码,除了这次,源代码来自AmazonS3。在从S3获取流之前,我们不会开始阅读。然而,这一次,read循环运行了数千次,而它应该只读取5次

    InputStream is;
    long t1 = System.currentTimeMillis();
    is = getS3().getFileFromBucket(S3Path,input);
    long t2 = System.currentTimeMillis();

    System.out.print("Time to get file " + input + " from S3: ");
    System.out.println((t2-t1) + "ms");

    int read = 0;
    int buf_size = 1024*1024*2;
    byte[] buf = new byte[buf_size];

    ByteArrayOutputStream baos = new ByteArrayOutputStream(buf_size);
    long t3 = System.currentTimeMillis();
    int i = 0;

    while ((read = is.read(buf)) != -1) {
        baos.write(buf,0,read);
        if ((i % 100) == 0)
        System.out.println("reading for the " + i + "th time");
        i++;
    }
    long t4 = System.currentTimeMillis();

    System.out.println("Time to read = " + (t4-t3) + "ms");
结果如下:

Time to get file test.jpg from S3: 2456ms
reading for the 0th time
reading for the 100th time
reading for the 200th time
reading for the 300th time
reading for the 400th time
reading for the 500th time
reading for the 600th time
reading for the 700th time
reading for the 800th time
reading for the 900th time
reading for the 1000th time
reading for the 1100th time
reading for the 1200th time
reading for the 1300th time
reading for the 1400th time
Time to read = 14471ms
读取流所花费的时间在不同的运行中有所变化。有时需要60秒,有时需要15秒。速度不会超过15秒。在程序的每次测试运行中,read循环仍然会循环1400多次,尽管我认为应该只有5次,就像本地文件示例一样


当源通过网络时,即使我们已经从网络源获取完文件,inputstream也是这样工作的吗?提前感谢您的帮助。

我认为这不是java特有的。当您从网络读取数据时,对操作系统的实际读取调用将一次返回一个数据包,无论您分配的缓冲区有多大。如果您检查读取数据的大小(您的读取变量),它应该显示所使用的网络数据包的大小


这就是为什么人们使用单独的线程从网络中读取数据,并通过使用异步i/o技术避免阻塞的原因之一。

正如@imel96所指出的,文档中没有任何内容可以保证您所期望的行为。您永远不会从套接字一次读取2MB,因为套接字接收缓冲区通常没有那么大,与带宽等其他因素无关。

谢谢您的回复。所以就因为我写。。。is=getFileFromS3()。。。。这并不意味着该文件被下载到本地内存以便快速访问?我想我很困惑,因为我放了一些调试行,它显示了从S3“下载”文件的方法的运行时间是2.5秒。@imel96:这是真的吗?根据文档:
将此输入流中最多字节的数据读取到字节数组中。此方法会一直阻止,直到某些输入可用。
返回:
读取到缓冲区的总字节数,或者-1(如果由于到达流的结尾而没有更多数据)
我的答案仍然符合文档要求。文档没有说它将阻塞,直到它完成对流的读取,它只是阻塞,直到一些输入可用。底层recv(2)标准规定,对于基于流的套接字,“数据一旦可用,应立即返回给用户,不得丢弃任何数据”。谢谢您的回复。所以,你们要说的是,即使该方法已经完成并将inputstream对象返回给第二个示例第3行中的变量“is”,我仍然在从网络套接字读取,并且我没有本地的inputstream“blob”来读取/操作?该示例中的inputstream对象“is”只是一个“文件描述符”。在您开始读取之前,它没有文件的任何部分。