0

I have been trying to read data for hackerrank questions, however, although I have tried the following methods, none of them worked properly as explained below. The input file format is like that:

5
2 6 8 9 13

1. Normally I read values with the same format from a local txt file. But when using a local txt file, the code does not work as expected. So, I try to read url with the same method, it does not work as well:

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. I tried to enter inputs via keyboard, but this also does not work when testing the code in hackerrank.

So, as far as I see, there is a remote txt file and I need to read inputs via Scanner (at least I prefer to use Scanner).

How can I read the values from this remote url?

  • “…it does not work as well…” Elaborate please. What were you expecting? What did you see instead? Are you getting an exception? If so, post its full stack trace. – VGR Jul 04 '20 at 20:04
  • Does this answer your question? [Read AWS s3 File to Java code](https://stackoverflow.com/questions/28568635/read-aws-s3-file-to-java-code) – Arvind Kumar Avinash Jul 04 '20 at 20:14
  • @VGR Throws errors that you can see and examine by just copying the code above easily. Otherwise it is not useful to include all the stacktrace etc. –  Jul 04 '20 at 20:20
  • I tried your code with the link you posted and it worked. – dariosicily Jul 04 '20 at 20:22
  • @dariosicily Which one did you use? `Scanner scan = new Scanner(new URL(url).openStream()); //it does not work as well` ? or the other one? It throws index out of bounds error :( –  Jul 04 '20 at 20:39
  • `URL url = new URL(name);InputStream urlStream = url.openStream();Scanner scan = new Scanner(urlStream);` – dariosicily Jul 04 '20 at 20:40
  • @dariosicily No, I do not mean the url (I also used it but shortened in the question for brevity). Which scanner method did you use? Why did not post the code you tried as answer? Thanks. –  Jul 04 '20 at 20:42

1 Answers1

1
  • You have to use the "actual URI" along with AWSAccessKeyId, and Signature which is what the endpoint requires.
  • You are using https://hr-testcases-us-east-1.s3.amazonaws.com/1234/input.txt but that will throw 403 Forbidden.

curl request

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>

Working example:

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();
       }
     }
}

output:

6
1 2 3 4 10 11

If you only care about second line of input you can collect them with following code.

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;
        }
    }
prayagupa
  • 30,204
  • 14
  • 155
  • 192
  • Thanks for reply, seems to be an elegant solution. But I tried to use `int[] list` instead of `StringBuilder` and it does not work. I use a counter value starting from 0 and increase its value in `while` loop. Is it possible to use int array? –  Jul 04 '20 at 20:35
  • As soon as you created an instance of `Scanner` you can use its methods `nextInt()` – Nowhere Man Jul 04 '20 at 20:38
  • 1
    Your Scanner methods are mismatched. If you use `hasNext()`, you need to read with `next()`. If you use `hasNextLine()`, you need to read with `nextLine()`. Of course, the question seems to be expecting int values, so `hasNextInt()` and `nextInt()` seem like the best choice. – VGR Jul 04 '20 at 20:45
  • 1
    You need to close the Scanner in finally bloc or try(Scanner scanner = new Scanner(new URL(url).openStream())){ //rest of your code } – Katy Jul 04 '20 at 20:56
  • @AlexRudenko & VGR & M.Mas, thanks a lot for your valuable comments. However, when I use the second example (using ArrayList), I encounter *"Exception in thread "main" java.io.IOException: Server returned HTTP response code: 403 for URL:"* error. Do I have to send the parameters separately? –  Jul 05 '20 at 08:25
  • @prayagupd On the other hand, I already use the full url in my example and short the url in question for brevity. However, it does not work. How to fix it? –  Jul 05 '20 at 08:27
  • And even this code works, **is there anything to be applied in order to make this code work in hackerrank?** –  Jul 05 '20 at 08:28
  • @Jason please don't mix the "actual URL" not working with java code. `403` means the endpoint you are trying to hit is wrong, it has nothing to do with java. HackerRank is not going to use same endpoint since that is not secure. My guess is change the `Expires` field in request which will also change `Signature`. – prayagupa Jul 05 '20 at 19:51
  • @prayagupd Thanks a lot, you are right. On the other hand, do you have experience about how to update the code working on Hackerrank to make it work locally on Eclipse, etc? –  Jul 06 '20 at 18:44