【问题标题】:How should I read inputs from S3 URL?我应该如何从 S3 URL 读取输入?
【发布时间】:2020-07-05 05:04:46
【问题描述】:

我一直在尝试读取有关hackerrank 问题的数据,但是,尽管我尝试了以下方法,但它们都无法正常工作,如下所述。输入文件格式是这样的:

5
2 6 8 9 13

1. 通常我会从本地 txt 文件中读取相同格式的值。但是当使用本地 txt 文件时,代码无法按预期工作。所以,我尝试用相同的方法读取 url,它也不起作用:

String url= "https://hr-testcases-us-east-1.s3.amazonaws.com/1234/input.txt";
Scanner scan = new Scanner(new File(url)); //I can read from local txt file by using this
Scanner scan = new Scanner(new URL(url).openStream()); //it does not work as well

2.我尝试通过键盘输入,但是在hackerrank中测试代码时这也不起作用。

所以,据我所知,有一个远程 txt 文件,我需要通过 Scanner 读取输入(至少我更喜欢使用 Scanner)。

如何从this 远程网址读取值?

【问题讨论】:

  • “……它也不行……”请详细说明。你期待什么?你看到了什么?你有例外吗?如果是这样,请发布其完整的堆栈跟踪。
  • 这能回答你的问题吗? Read AWS s3 File to Java code
  • @VGR 抛出您可以通过轻松复制上面的代码来查看和检查的错误。否则,包含所有堆栈跟踪等是没有用的。
  • 我用您发布的链接尝试了您的代码,并且成功了。
  • @dariosicily 你用的是哪一个? Scanner scan = new Scanner(new URL(url).openStream()); //it does not work as well ?还是另一个?它抛出索引越界错误:(

标签: java amazon-s3 input java.util.scanner


【解决方案1】:
  • 您必须使用“实际 URI”以及 AWSAccessKeyIdSignature,这是端点需要的。
  • 您正在使用https://hr-testcases-us-east-1.s3.amazonaws.com/1234/input.txt,但这会抛出403 Forbidden

curl请求

curl -v "https://hr-testcases-us-east-1.s3.amazonaws.com/1234/input.txt"
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>6EC610D00EEF232C</RequestId><HostId>8KIOxrFqKNbjGobVWebrK8hC3QCWm29bQQFsKsvPD4mNooVUbg5E1bXPczUSD3TceWV+Z4jHueM=</HostId></Error>

工作示例:

import java.io.IOException;
import java.net.URL;
import java.util.Scanner;

public class ReadUriData {

    public static void main(String[] args) {

        final String accessId="AKIAJ4WZFDFQTZRGO3QA";
        final String signature="JXK3B9GtxpgSEosmgvPBg%2B0UBuI%3D";
        final String url = String.format(
                "https://hr-testcases-us-east-1.s3.amazonaws.com/9828/input00.txt?AWSAccessKeyId=%s&Expires=1593897931&Signature=%s&response-content-type=text/plain",
                accessId, signature
        );

        try {
            String data = readFromUri(url);
            System.out.println(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String readFromUri(String url) throws IOException {
        try (Scanner scanned = new Scanner(new URL(url).openStream())) {

          StringBuilder data = new StringBuilder();
          while(scanned.hasNextLine()){
              data.append(scanned.nextLine()).append("\n");
          }
          return data.toString();
       }
     }
}

输出:

6
1 2 3 4 10 11

如果您只关心第二行输入,您可以使用以下代码收集它们。

private static List<Integer> readFromUri(String url) throws IOException {
        int ROW_FOR_NUMBER_OF_INPUTS = 0;
        try (Scanner scanned = new Scanner(new URL(url).openStream())) {
            List<Integer> data = new ArrayList<>();

            int cursor = 0;
            while (scanned.hasNextInt()) {
                if (cursor == ROW_FOR_NUMBER_OF_INPUTS) {
                    scanned.nextInt();
                } else {
                    data.add(scanned.nextInt());
                }
                cursor++;
            }
            return data;
        }
    }

【讨论】:

  • 感谢您的回复,似乎是一个优雅的解决方案。但我尝试使用int[] list 而不是StringBuilder,但它不起作用。我使用从 0 开始的计数器值并在 while 循环中增加其值。是否可以使用int数组?
  • 一旦您创建了Scanner 的实例,您就可以使用它的方法nextInt()
  • 您的扫描仪方法不匹配。如果您使用hasNext(),则需要使用next() 阅读。如果您使用hasNextLine(),则需要使用nextLine() 阅读。当然,问题似乎是期待 int 值,所以 hasNextInt()nextInt() 似乎是最好的选择。
  • 您需要在 finally bloc 中关闭 Scanner 或 try(Scanner scanner = new Scanner(new URL(url).openStream())){ //其余代码 }
  • @AlexRudenko & VGR & M.Mas,非常感谢您宝贵的 cmets。但是,当我使用第二个示例(使用 ArrayList)时,我遇到 "Exception in thread "main" java.io.IOException: Server returned HTTP response code: 403 for URL:" 错误.需要单独发送参数吗?
猜你喜欢
  • 2011-03-29
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多