Changing Scanner's input after hasNext() returned false

how to change scanner settings windows 10
how to change scan destination folder windows 10
how to change barcode scanner settings
windows fax and scan
change default scan location windows 7
scan profiles windows 10
windows fax and scan change resolution
scan settings chromebook

I'm using my custom InputStream for Scanner and want to change it. But after first reading and changing data in the InputStream it stops.

Can I modify my code for the second reading? Which way?

Upd I use this code with other programs and redirect their standard input to mine. So I need to change System.in and cannot recreate Scanner.

Here are my classes:

class CRStream extends InputStream {
  private ByteArrayInputStream in;
  public synchronized int read() throws IOException {
     int x = in.read();
    return x;
  }
  public synchronized int read(byte[] bytes, int off, int len) throws IOException {
    return in.read(bytes, off, 1);
  }
  public void set(String utf8str) throws IOException{
     try{
        in = new ByteArrayInputStream(utf8str.getBytes(StandardCharsets.UTF_8.name()));
    }
    catch (UnsupportedEncodingException e){}
  }
}

and example of using

public class Main {
    public static void main(String[] args) throws IOException {
         CRStream in = new CRStream();
         System.setIn(in);
         Scanner scanner = new Scanner(System.in);
         //Everything is OK
         in.set("Word1 Ok Word2 Ok");
         while (scanner.hasNext()){
             System.out.println(scanner.next());
         }
         //Does not work... Prints nothing
         in.set("WORD3 Ok WORD4 Ok");
         while (scanner.hasNext()){
             System.out.println(scanner.next());
         }
    }
}

This is a second example

A simple Client program

class ClientProgram {
    public static Scanner in = new Scanner(System.in);
    public static void main(String[] args) {
        System.out.println(in.next());
    }
}

I test it with code

public class Main {
    public static void main(String[] args) {
         CRStream in = new CRStream();
         System.setIn(in);
         in.set("Test1");
         ClientProgram.main(new String[0]);
         in.set("Test2");
         ClientProgram.main(new String[0]);

    }
}

And it falls with NoSuchElementException on second test.

Just curious why you're jumping through so many hoops when a scanner can read from a string directly:

public static void main(String[] args) throws IOException {

     Scanner scanner = new Scanner("Word1 Ok Word2 Ok");
     while (scanner.hasNext()){
         System.out.println(scanner.next());
     }

     scanner = new Scanner("WORD3 Ok WORD4 Ok");
     while (scanner.hasNext()){
         System.out.println(scanner.next());
     }

If you want the Ok to be delimiters you can call useDelimiter(" Ok ") on your scanner

As to the actual problem, I suspect that internally scanner might be buffering your input stream and not realise you've pulled a switcheroo on it; perhaps make a new scanner anyway or reset() your crinputstream. There is also no need to replace system inputstream with yours then connect scanner to system in; scanner can read from your input stream without going via system.in

Changing a Scan Profile, The [Scan Profiles] window appears. Select a profile, and then click [Edit]. The changed profile dialog box appears. Configure the necessary settings. When you connect a scanner to your device or add a new scanner to your home network, you can usually start scanning pictures and documents right away. If your scanner doesn't automatically install, here's some help to get things working. Select one of the following sections, or select Show all. Any section you choose will open to show you more info on using your scanner.

Instead of implementing a dodgy new InputStream, you should probably wrap around all the inputs you get and just return the strings being parsed. That way, your wrapper class can maintain the Scanner it uses depending on what it's reading at the moment.

class TokenProvider {
    Queue<Scanner> readFrom = new Deque<Scanner>();
    Scanner currentScanner;

    public void addSource(String string) {
        readFrom.add(new Scanner(string));
    }
    public boolean hasNext() {
        nextScanner();
        return currentScanner != null && currentScanner.hasNext();        
    }
    public String next() {
        return currentScanner.next();
    }
    private void nextScanner() {
        while (currentScanner == null || !currentScanner.hasNext()) {
            if (readFrom.isEmpty()) break;
            currentScanner = readFrom.poll();
        }
    }
}

Now your driver code looks like this

 TokenProvider in = new TokenProvider();
 in.addSource("Word1 Ok Word2 Ok");
 while (in.hasNext()){
     System.out.println(in.next());
 }
 // all data has been iterated, but we can add more now
 in.addSource("WORD3 Ok WORD4 Ok");
 while (in.hasNext()){
     System.out.println(in.next());
 }

HP ScanJet Scanners, Click on Ok and Scan the document to a desired location. HP Scanners Tools utility: In HP Scanner tools utility you have the option called PDF setting and you can  To change the default destination to the desired one, please follow the below steps: 1.Launch the HP Document Viewer. 2.Click on Scan a new document (icon on the menu bar) 3.Select the scanner model and then click on Ok. 4.Please select the “Scan to” as save to file and the File type as .rtf or

Scanner maintains internal state, sets a flag "sourceClosed=true" once current source runs out. Any future access to Scanner will be rejected since Scanner thinks it's empty despite changing the source stream, as the flag does not roll back. I don't see a way to circumvent this without a customised scanner implementation. Rather than going into that rabbit-hole, try to use a new Scanner for each read if possible.

In the second client, don't maintain a static Scanner, instead

class ClientProgram {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println(in.next());
    }
}

Changing the Default Document Scanner in OfficeMate, Issue: An old or incorrect document scanner is the only scanner that can be selected when scanning eDocuments in OfficeMate/ExamWRITER. Windows Fax and Scan - changing scanner I need to change the printer/scanner used with Windows Fax and Scan but there doesn't appear to be any option to do so. When I select scanner I get a list of 2 obsolete scanners which I need to delete but there isn't an option to remove them, nor is there an option to add/select my wireless scanner.

Making Changes to Scanner Settings, Click Scan to start scanning. The scanned images are sent to the application or saved in the specified folder. Select the suitable resolution. When you specify a  To set the default scanner, go into Tools > Scan Settings If you have multiple scanners configured (which you do I believe), select that one and click "Set as Default". If you can't find your scanner, click Add to create a new scanner profile. You'll see the Scanner dropdown menu, and from there, you should be able to select your scanner.

Selecting Epson Scan Settings, See Changing the Scan Mode for instructions on switching to Professional Mode. See Selecting Basic Settings for scanning steps. Top. Selecting File Save  In HP Solution Center, click Scan Document or Scan Picture to view available scan shortcuts and settings. Click one of the shortcuts that matches the file type and resulting action you want. Change any of the shortcut default settings in the right side of the window, if necessary.

Scanner Settings Screen, Use the Scanner Settings screen to temporarily change a scanner's settings. Display this screen by clicking the Scanner Settings toolbar button in the Batch  Use the resolution and quality settings in the HP Scan software to change the resolution and quality of your scan. In HP Scan, select a shortcut, and then click More . Click the Image tab.

Comments
  • What's the purpose of redirecting System.in? Why not just wrap your Scanner directly around in?
  • It the real project I work with other programs which use Scanner from System.in. So I redirect their standart input to mine.
  • It's common to use a Scanner with System.in, but it's not an absolute requirement, You can read any InputStream with a Scanner
  • All programs I am working with read data by Scanner from System.in. My purpose is to give them my own input. Everything works fine, then the other code create Scanner in a function. So I can call it several times and give it new InputStream. But if that code create static Scanner variable, it does not work. In this case scanner is created only once. So the question is "Can we continue use scanner with the same InputStream after hasNext() returned false?
  • The issue is your input stream doesn't follow protocol by allowing to set data to it after it has been read entirely. You cannot return -1 on a read once, then something valid later and expect client classes to be fine with it.
  • Unfortunatelly I cannot recreate Scanner in my code.
  • What does that mean?
  • I use this code with other programs and redirect their standart input to mine. So I need to change System.in and cannot recreate Scanner.
  • You keep saying that same thing but it doesn't really make sense to me. You're overwriting system.in with your own thing so how is that even capable of reading another program's output to system.in? If you can't make a new scanner, reset it after you put new data in the crstream. Also check that your crstream works to see the new data (use it directly and check it works for read() set read() - does it give you what you expect?) if crstream isn't even used in your app please give us an actual example of real life failing code, not this hard to understand fake version?
  • I added the second example to the question
  • I explained poorly at the beginning... Please, look at the second example, I added to the question. It seems to me I cannot wrap client's Scanner, because I know just nothing about it, only that it exists and reads from System.in. Nothing more.