-2

I have a problem with time.

I currently develop an app in Java where I have to make a network analyzer.

For that I use JPCAP to capture all the packets, and write them in a file, and from there I will put them bulk in DB.

The problem is when I am writting in file the entire object, like this,

UDPPacket udpPacket = (UDPPacket)packet
wtf.writeToFile("packets.txt",udpPacket +"\n");

everything is working nice and smooth, but when I try to write like this

    String str=""+udpPacket.src_ip+" "+udpPacket.dst_ip+""
+udpPacket.src_port+" "+udpPacket.dst_port+" "+udpPacket.protocol +
" Wi-fi "+udpPacket.dst_ip.getCanonicalHostName()+"\n";
     wtf.writeToFile("packets.txt",str +"\n");

writting in file is during lot more time.

the function to write in file is this

public void writeToFile(String name, String str){
        try{
            PrintWriter writer = new PrintWriter(new FileOutputStream(new File(name),this.restart));
            if(!str.equalsIgnoreCase("0")){
                writer.append(str);
                this.restart=true;
            }
            else {
                this.restart=false;
                writer.print("");
            }
            writer.close();
        } catch (IOException e) {
          System.out.println(e);
        }
    }

Can anyone give me a hit, whats the best way to do this?

Thanks a lot

EDIT:

7354.120266 ns - packet print

241471.110451 ns - with StringBuilder

Paul F.
  • 17
  • 1
  • 8
  • A couple of notes. First, doesn't the `getCanonicalHostName()` have to do a DNS resolve? Second, use a `StringBuilder` rather than all of the String concatinations. – KevinO May 01 '17 at 21:35
  • With the function getCanonicalHostName() its not a problem, its almost working, the method extract some info from header, but isnt a big problem. using StringBuilder doesn't make any good. Time difference is also big, 7354.120266 ns - for packet print 241471.110451 ns - with StringBuilder – Paul F. May 01 '17 at 21:57
  • And the output contents when using the `udpPacket` write are the same as when you build the String? I don't have a working example at the moment to check. Side consideration: it may be more efficient to not open/close the file on every call to `writeToFile()`. – KevinO May 01 '17 at 22:21
  • OK, I found the source code for UDPPacket. Its `.toString()` has `getSourceAddress()/getSourcePort()` and `getDestinationAddress()/getDestinationPort()` and some length information. I would suspect that something, such as `getCanonicalHostName()` is slow. I might suggest trying subsets of the output to verify the timing. – KevinO May 01 '17 at 22:27
  • Well, even if I write only 2 attributes, such as destination ip and source ip, it also goes slow... so I dont think that's the problem – Paul F. May 01 '17 at 23:08

2 Answers2

0

Keep the PrintWriter open. Don't open and close it for every line you want to write to the file. And don't flush it either: just close it when you exit. Basically you should remove your writeToFile() method and just call PrintWriter.write() or whatever directly when necessary.

NB You are writing text, not objects.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Even if I make System.out.println(str) its working slowly. So I dont think this is the problem. But it's an improvement. Thanks – Paul F. May 02 '17 at 07:09
  • If it isn't the problem how can it possibly be an improvement? It is working as slowly as `System.out.println()`, which is going to be *very* slow in most cases, much slower than writing to an already-open file via a `Writer` that does application-side buffering. Your testing methodology is flawed. Try it my way. If there's still a problem you're entitled to assert this isn't the problem. Not before. – user207421 May 02 '17 at 09:43
0

I found the problem

as @KevinO said, getCanonicalHostName() was the problem.

Thanks a lot.

Paul F.
  • 17
  • 1
  • 8