-1

I'm facing a problem that i really don't understand. I designed my program to read info from files and then generate reports about it.

At the first time, I open all the files that I need:

clientesarq = new File(args[1]);
fornecedoresarq = new File(args[3]);
produtosarq = new File(args[5]);

then I use a java.util.Scanner to loop through them:

leitor = new Scanner(clientesarq);
    leitor.nextLine();

    /* leitura e armazenamento dos clientes em mapa */
    while(leitor.hasNextLine()) {
        Cliente c = pd.novoCliente(leitor);
        clientes.addCliente(c);
    }

    leitor = new Scanner(fornecedoresarq);
    leitor.nextLine();

    /* leitura e arazenaento dos fornecedores em mapa */
    while(leitor.hasNextLine()) {
        Fornecedor f = pd.novoFornecedor(leitor);
        fornecedores.addFornecedor(f);
    }

when my program reaches this part of the code, the JVM throws to me NoSuchElementException.

leitor = new Scanner(produtosarq);
leitor.nextLine(); /* EXCEPTION HERE */

/* leitura e armazenamento dos produtos em mapa */
while(leitor.hasNextLine()) {
    Produto p = pd.novoProduto(leitor);
    produtos.addProduto(p);
}

I really want to know why the hell I am getting this excpetion, as you can see, the code is exactly the same as the other ones. Any?

You can get all needed files here: https://www.dropbox.com/sh/c48roudfwuj7qzu/AAAMn_OFGXJFHEjVJyZ7piCPa

ddz
  • 525
  • 3
  • 13
  • What command line arguments are you using? Try printing them, `System.out.println(Arrays.toString(args));` Presumably the file at `args[5]` has no lines. – Elliott Frisch Jun 28 '14 at 02:57
  • why are you doing this? leitor.nextLine();? is there any purpose? (if you dont check if it hasNextLine(), you can get that exception trying to get it.) – Ed Morales Jun 28 '14 at 02:58
  • What do you do in `pd.novoProduto()` ? – Nir Alfasi Jun 28 '14 at 02:58
  • 1
    possible duplicate of [How to use the Scanner class in java?](http://stackoverflow.com/questions/11871520/how-to-use-the-scanner-class-in-java) – Nir Alfasi Jun 28 '14 at 02:59
  • @ElliottFrisch yes it has, I already checked what file is open and `produtosarq.length()` shows to me the size of file. @EdwardM.B. the file has a first line that must be ignored. That's why I am doing it. – ddz Jun 28 '14 at 03:01
  • You're not using your Scanner right. You need to call `nextLine()` inside of the loop that checks `hasNextLine()`. Please read the tutorial on its use. Your use of these methods is almost random and makes no sense. – Hovercraft Full Of Eels Jun 28 '14 at 03:01
  • @alfasin doesn't matter, as you can see my program never reach that loop. – ddz Jun 28 '14 at 03:01
  • 1
    Just because a file has length, doesn't mean it has an ascii new-line. – Elliott Frisch Jun 28 '14 at 03:03
  • 1
    You should check that there is something to read before you try and read it: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNext() – Nir Alfasi Jun 28 '14 at 03:04
  • So why with the two files above it I don't get this error? – ddz Jun 28 '14 at 03:04
  • 2
    You're asking "why my code won't work" without giving us the ability to test your code. Not good. You should post a [Minimal, Complete, and Verifiable Example Program](http://stackoverflow.com/help/mcve) complete with example text files. – Hovercraft Full Of Eels Jun 28 '14 at 03:06
  • Ok, I'll edit in a few secs. – ddz Jun 28 '14 at 03:07
  • @HovercraftFullOfEels done. – ddz Jun 28 '14 at 03:12
  • Please first read the link that I provided before you can say that you're done. I'll wait for the real thing. – Hovercraft Full Of Eels Jun 28 '14 at 03:13
  • 2
    Luiz, please. Read the link. You need to understand that we are volunteers, and we are trying to help you with **your** problem. To best allow us to do this, you should post a minimal complete program here on this site as an edit to your question, not as a link. The link I've provided to the help section on this site explains all this. If your thoughts are that you've too much code to post here, then you've got too much code for volunteers to go through. What you'll want to do is to create a new ***small, minimal*** program, one that reads two files, and one that reproduces your problem. – Hovercraft Full Of Eels Jun 28 '14 at 03:26
  • Yes, this is asking extra effort from you, but you're asking extra effort from us for free, and so I see it as a fair trade. – Hovercraft Full Of Eels Jun 28 '14 at 03:27
  • Could you, please, just try to read the file `produtos.csv`? I created a txt file with the same content of `produtos.csv` and my program worked fine. Was it a problem with the file? I have no idea why it worked. – ddz Jun 28 '14 at 03:32

3 Answers3

1

Use UTF-8 character set to read from file which is able to represent every character in Unicode Format.

Here it will convert Bytes from the file into characters using the specified charset(Here UTF-8) and will make it readable for Scanner I guess.

Scanner input = new Scanner(new File("filename"),"UTF-8");
ΔȺȾΔ
  • 21,571
  • 10
  • 52
  • 80
1

Specifying the charset did not fix the issue for me. This post is comment-like as I have not fully discovered the issue, but I am making an attempt at explaining the why portion of the question with what I have found thus far.

I found another post with the same problem as a secondary resource. In both cases, the first line of the files ends with ASCII character 13 carriage return which I would have thought should be picked up by the Scanner as a line separator. As a sanity check, I performed a BufferedReader readLine() and it works fine. Digging deeper, I cloned the source of Scanner and wound up on readInput line 849 : n = source.read(buf);.

After determining the type of source was sun.nio.cs.StreamDecoder, I cloned the class and investigated readImpl. In both cases, line 324 int n = readBytes(); reads the entire file into the buffer hitting the continue and coming back around to line 316 CoderResult cr = decoder.decode(bb, cb, eof); At this point cr is wrapping a MalformedInputException which gets consumed by Scanner catch (IOException ioe).

Since I was able to reproduce this issue in my cloned source, I printed the stacktrace:

java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at javaapplication1.StreamDecoder.implRead(StreamDecoder.java:349)
at javaapplication1.StreamDecoder.read(StreamDecoder.java:188)
at java.io.Reader.read(Reader.java:100)
at javaapplication1.MyScanner.readInput(MyScanner.java:844)
at javaapplication1.MyScanner.findWithinHorizon(MyScanner.java:1789)
at javaapplication1.MyScanner.nextLine(MyScanner.java:1629)  

The decoder at runtime is sun.nio.cs.UTF_8. I've stopped digging at this point as it is way into the AM hours, I may edit in further findings.

The main question now is why the final single character of input kills the decoder.

Community
  • 1
  • 1
Origineil
  • 3,048
  • 2
  • 10
  • 17
  • In this post you mentioned, the problem was that the file was corrupted. I'm not sure if that's my case, since I can see its contents with MS Excel or another text editor. – ddz Jun 28 '14 at 15:29
  • 1
    The other post's file has contents that are viewable too. At this point I believe the problem is in the `EOF` (end of file). Somehow I think it is in a corrupted state causing issues. – Origineil Jun 28 '14 at 16:20
0

Just a guess but maybe the file you are trying to read doesnt have any information. Always check if it has a next line before getting that next line.

if(scanner.hasNextLine()){
    String line = scanner.nextLine();
}
Ed Morales
  • 1,021
  • 5
  • 9
  • yes it has, I already checked what file is open and produtosarq.length() shows to me the size of file. the file has a first line that must be ignored. That's why I am doing it. – ddz Jun 28 '14 at 03:02
  • well, that exception is thrown when the nextLine doesnt have anything to return so... – Ed Morales Jun 28 '14 at 03:04
  • The point of my question is: the file is open, it exists in the folder and yes, it have lines to be read, so why am I getting this? – ddz Jun 28 '14 at 03:06