1

I have been banging my head against the wall about this for quite some time now and would really appreciate some help.
I have 2 streams and what I want is to exclude elements from one stream if they are in the other stream.
I am trying to write a program to find all audio files and then writes them to a file. You give it a folder to check and it finds all the audio files in that folder and writes them all to a file. That part works great. The problem comes into play if you give it the same folder again, I want to be able to exclude the audio files that are already there. Here is the code in question:

Stream<Path> s = Files.walk(folder.toPath()).filter(p -> isAudio(p));

and then the isAudio(Path p) method:

try
{
    if (Files.probeContentType(p).startsWith("audio"))
    {
        if (PS != null)
        {
            System.out.println("boo");
            System.out.println(PS.noneMatch(t -> t.equals(p.toString())));
            System.out.println("boo2");
        }
        return true;
    }
}
catch (Exception e) {System.err.println(e); }
return false;

PS is my second stream and it read in from the file. I have tested it and it is correct. my problem is that the results of the noneMatch aren't printed and "boo2" is NEVER displayed. It gets skipped every single time. It jumps to "return false;" every single time and I am completely lost for an answer. Please, any help I can get would be greatly appreciated!!

roeygol
  • 4,908
  • 9
  • 51
  • 88
  • What is this PS thing and where is it declared? Obviously whatever that noneMatch thing is doing is part of your problem. Maybe it is blocking on something? Maybe it is failing in some weird way? Catch Throwable instead of just checked exceptions. If anything weird is happening, you'll want to know. Next step is hooking up a debugger and stepping inside the noneMatch method to find out what it is doing. – Jilles van Gurp Jan 23 '17 at 10:03

2 Answers2

0

Not sure how your system is configured, but maybe your stderr output is not viewable. Can you try just replacing your catch clause with the following?

catch (Exception e) {
   System.out.println("Exception encountered: " + e);
   System.err.println(e); 
 }

Then try to re-run your code, and maybe you'll be able to see the "Exception encountered" message, along with the exception that's being thrown.

mjuarez
  • 16,372
  • 11
  • 56
  • 73
  • Exception encountered: java.lang.IllegalStateException: stream has already been operated upon or closed – bobthebob55 Jan 22 '17 at 04:50
  • How do I get around that? – bobthebob55 Jan 22 '17 at 04:56
  • seems like you already performed a terminal operation on the PS stream you're using. "Terminal operations, such as Stream.forEach or IntStream.sum, may traverse the stream to produce a result or a side-effect. After the terminal operation is performed, the stream pipeline is considered consumed, and can no longer be used; if you need to traverse the same data source again, you must return to the data source to get a new stream." - https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html – Hesham Attia Jan 22 '17 at 05:02
  • @bobthebob55 the problem is your stream "PS" is already closed, or it has no more data. So you should check for that, before calling PS.noneMatch() – mjuarez Jan 22 '17 at 05:02
  • the only thing that I have done with PS stream is to set its value. PS = IO.readFile(); that is the only thing done to PS. I have a seperate class that reads a file and assigns the stream to PS. what closes the stream? – bobthebob55 Jan 22 '17 at 05:12
  • so, what I gathered from that read is that my best bet would be to read in the File everytime to check if that file is new or not? wouldn't that be a waste of time? – bobthebob55 Jan 22 '17 at 05:56
  • @bobthebob55, the problem is definitely the PS variable: noneMatch is considered a terminal operation, and for every call to `isAutio` besides the very first one you will need to reassign the `PS` again to get anything out. I don't quite know what it's for, but looks like it somehow contains paths that are already processed in some way. In that case, you might want to switch out from using stream there and opt for some other data structure that is populated from a stream, but only consumes from it once and stores each element in a set or something. – M. Prokhorov Jan 31 '17 at 10:38
0

Maybe you should try to split the calls into two:

  1. Filter for files with audio in their name
  2. distinct them by there key (name)

Something like this (pseudo code):

yourFiles.filter(t -> "*audio*".matches(t)).filter(distinctByKey( e -> e.getAbsolutePath())

Here I found the answer to problem 2 (stackoverflow link). There is the code for the distinctByKey method.

Community
  • 1
  • 1
Dominik Reinert
  • 1,075
  • 3
  • 12
  • 26