When runing this method i get wrong number of arguments exception like this :
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at javafxcyberwind.Participant_MethodsIMPL.execution(Participant_MethodsIMPL.java:85)
The exception is in the comment line, despite the arguments entered are correct, this is my code:
#Override
public void execution(String cls, String ip, Object... par) throws InvocationTargetException, RemoteException {
try {
URLClassLoader loader = new URLClassLoader(new URL[]{new URL("file:///" + prep)});
Class<?> c = loader.loadClass(cls);
Object j = c.newInstance();
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
ArrayList<Object> tab = new ArrayList<>();
if (method.getReturnType() == int.class || method.getReturnType() == String.class || method.getReturnType() == boolean.class || method.getReturnType() == double.class) {
tab.clear();
tab.addAll(Arrays.asList(par));
int i = 0;
HashMap<Integer, File> lif = new HashMap<>();
File file = null;
for (Object o : tab) {
if (o.getClass().equals(Fichier.class)) {
String nomfichier = ((Fichier) o).getNom();
file = new File(prep + nomfichier);
lif.put(i, file);
}
i++;
}
for (Map.Entry<Integer, File> entry : lif.entrySet()) {
tab.remove(entry.getKey());
tab.add(entry.getKey(), entry.getValue());
}
k = method.invoke(j, tab.toArray());//line of exception
if (file != null) {
file.delete();
}
}
if (method.getReturnType().toString().equals("class java.io.File")) {
tab.clear();
tab.addAll(Arrays.asList(par));
int i = 0;
int t = -1;
String nomfichier = null;
File file = null;
for (Object o : tab) {
if (o.getClass().equals(Fichier.class)) {
nomfichier = ((Fichier) o).getNom();
file = new File(prep + nomfichier);
t = i;
}
i++;
}
if (t != -1) {
tab.remove(t);
tab.add(t, file);
}
k = method.invoke(j, tab.toArray());
if (file != null) {
file.delete();
}
fff = nomfichier.replace(nomfichier, cls + "_" + nomfichier);
File fres = new File(prep + fff);
R.uploadToCloud(fff);
Socket s = new Socket(ip, R.getPort());
FileInputStream inf = new FileInputStream(fres);
ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
byte buf[] = new byte[1024];
int n;
while ((n = inf.read(buf)) != -1) {
out.write(buf, 0, n);
}
out.close();
inf.close();
s.close();
fres.delete();
}
}
} catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
Logger.getLogger(Participant_MethodsIMPL.class.getName()).log(Level.SEVERE, null, ex);
}
}
I can avoid the exception and make it work but as you see just for one file passed as an argument, this is the code :
if (method.getReturnType() == int.class || method.getReturnType() == String.class || method.getReturnType() == boolean.class || method.getReturnType() == double.class) {
tab.clear();
tab.addAll(Arrays.asList(par));
int i = 0;
int t = -1;
File file = null;
for (Object o : tab) {
if (o.getClass().equals(Fichier.class)) {//means there is an argument of type File
String nomfichier = ((Fichier) o).getNom();//getting the file name
file = new File(prep + nomfichier);//file that will replace the remote file
t = i;
}
i++;
}
if (t != -1) {//replacing the remote file
tab.remove(t);
tab.add(t, file);
}
k = method.invoke(j, tab.toArray());
if (file != null) {
file.delete();
}
}
This method is called remotely so i have to create a new file for each file passed as an argument known that the files are received in advance.
The problem is when passing more than one file as an argument, in this case, how can i create a list of files where each file have an id that equals i then just browse this list ? I tried to do this with HashMap like on top but i keep getting the exception !
I solved this by just replacing :
for (Map.Entry<Integer, File> entry : lif.entrySet()) {
tab.remove(entry.getKey());
tab.add(entry.getKey(), entry.getValue());
}
By :
lif.entrySet().stream().forEach(entry -> tab.set(entry.getKey(), entry.getValue()));
Related
FileInputStream fileInputStream = new FileInputStream(filePath);
XWPFDocument document = new XWPFDocument(fileInputStream);
for (XWPFParagraph p : document.getParagraphs()) {
Boolean isPrg=true;
XmlCursor cursor = p.getCTP().newCursor();
cursor.selectPath(
"declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//*/w:txbxContent/w:p/w:r");
List<XmlObject> ctrsintxtbx = new ArrayList<XmlObject>();
while (cursor.hasNextSelection()) {
cursor.toNextSelection();
XmlObject obj = cursor.getObject();
ctrsintxtbx.add(obj);
}
for (XmlObject obj : ctrsintxtbx) {
CTR ctr = CTR.Factory.parse(obj.newInputStream());
XWPFRun bufferrun = new XWPFRun(ctr, (IRunBody) p);
String text = bufferrun.getText(0);
if (text != null && text != "") {
isPrg= false;
text = text.replace("[RECEPIENT_NAME]", name).replace("[ADDRESS1]", address1).replace("LETTER_GEN_DT", date)
.replace("[ID]",sbsbid).replace("MEMR_RX_ID", memrid)
.replace("MEMR_MCTR_RX_GROUP", memrgroup).replace("MEMR_MCTR_RXBIN", memrrxbin)
.replace("MEMR_MCTR_PCN", memrpcn);
System.out.println("header line is "+ text);
if((address2 == null || address2.equals("")) && (address3 == null || address3.equals(""))) {
text = text.replace("[ADDRESS2]",city+", "+state+" "+zip).replace("[ADDRESS3]","").replace("[ZIP]", "").replace("[CITY]", "").replace("[STATE]", "");
}
else if((address2 != null && !address2.equals("")) && (address3 == null || address3.equals(""))) {
text = text.replace("[ADDRESS2]",address2).replace("[ADDRESS3]",city+", "+state+" "+zip).replace("[ZIP]", "").replace("[CITY]", "").replace("[STATE]", "");
}
else if((address2 == null || address2.equals("")) && (address3 != null && !address3.equals(""))) {
text = text.replace("[ADDRESS2]",address3).replace("[ADDRESS3]",city+", "+state+" "+zip).replace("[ZIP]", "").replace("[CITY]", "").replace("[STATE]", "");
}
else if((address2 != null && !address2.equals("")) && (address3 != null && !address3.equals(""))) {
text = text.replace("[ADDRESS2]",address2).replace("[ADDRESS3]",address3).replace("[ZIP]",zip).replace("[CITY]", city).replace("[STATE]", state);
}
bufferrun.setText(text,0);
}
obj.set(bufferrun.getCTR());
}
if(isPrg) {
String runTxt="";
p.getCTP().documentProperties();
for(int i = 0; i < p.getRuns().size(); i++)
{
runTxt=runTxt+ p.getRuns().get(i);
}
System.out.println("main footer is :"+runTxt);
runTxt=runTxt.replace("[RECEPIENT_NAME]", name).replace("[PDP_NAME]", pdpname)
.replace("[ENRL_EFF_DT]", enrolldate).replace("[GLBL_PHONE_NUMBER]", phoneNumber);
int psize= p.getRuns().size();
if(psize>1) {
for(int i = 0; i < psize-1; i++)
{
try
{
p.removeRun(psize - i - 1);
}
catch(Exception e)
{
//e.printStackTrace();
}
}
}
for(XWPFRun ffr:p.getRuns()) {
ffr.setText(runTxt,0);
break;
}
}
}
outFilePath = filePath.replace(".docx", "_convert.docx");
FileOutputStream out = new FileOutputStream(
new File(outFilePath));
document.write(out);
out.close();
System.out.println("Output.docx written successully");
} catch (IOException | SQLException e) {
System.out.println("We had an error while reading the Word Doc");
}
return outFilePath;
}
Input Text :
will automatically terminate without notice when the base Contract terminates for any reason
Output i am getting like this:
will automatically terminate without notice when the base Contract terminates for any reason
For output also i need Bold text format after replacing the words in documents
Expected Output is :
will automatically terminate without notice when the base Contract terminates for any reason
I'm trying to read gmail messages using showmsg.java in the javamail sample package, and I keep getting this error when I run it. The program compiles fine though.
Here's the error message:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/internet/ParseException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: javax.mail.internet.ParseException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
Here's the code:
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.event.*;
import javax.mail.internet.*;
/*
* Demo app that exercises the Message interfaces.
* Show information about and contents of messages.
*
* #author John Mani
* #author Bill Shannon
*/
public class msgshow {
static String protocol;
static String host = null;
static String user = null;
static String password = null;
static String mbox = null;
static String url = null;
static int port = -1;
static boolean verbose = false;
static boolean debug = false;
static boolean showStructure = false;
static boolean showMessage = false;
static boolean showAlert = false;
static boolean saveAttachments = false;
static int attnum = 1;
public static void main(String argv[]) {
int optind;
InputStream msgStream = System.in;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-v")) {
verbose = true;
} else if (argv[optind].equals("-D")) {
debug = true;
} else if (argv[optind].equals("-f")) {
mbox = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-p")) {
port = Integer.parseInt(argv[++optind]);
} else if (argv[optind].equals("-s")) {
showStructure = true;
} else if (argv[optind].equals("-S")) {
saveAttachments = true;
} else if (argv[optind].equals("-m")) {
showMessage = true;
} else if (argv[optind].equals("-a")) {
showAlert = true;
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: msgshow [-L url] [-T protocol] [-H host] [-p port] [-U user]");
System.out.println(
"\t[-P password] [-f mailbox] [msgnum ...] [-v] [-D] [-s] [-S] [-a]");
System.out.println(
"or msgshow -m [-v] [-D] [-s] [-S] [-f msg-file]");
System.exit(1);
} else {
break;
}
}
try {
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
session.setDebug(debug);
if (showMessage) {
MimeMessage msg;
if (mbox != null)
msg = new MimeMessage(session,
new BufferedInputStream(new FileInputStream(mbox)));
else
msg = new MimeMessage(session, msgStream);
dumpPart(msg);
System.exit(0);
}
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
if (showAlert) {
store.addStoreListener(new StoreListener() {
public void notification(StoreEvent e) {
String s;
if (e.getMessageType() == StoreEvent.ALERT)
s = "ALERT: ";
else
s = "NOTICE: ";
System.out.println(s + e.getMessage());
}
});
}
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, port, user, password);
else
store.connect();
}
// Open the Folder
Folder folder = store.getDefaultFolder();
if (folder == null) {
System.out.println("No default folder");
System.exit(1);
}
if (mbox == null)
mbox = "INBOX";
folder = folder.getFolder(mbox);
if (folder == null) {
System.out.println("Invalid folder");
System.exit(1);
}
// try to open read/write and if that fails try read-only
try {
folder.open(Folder.READ_WRITE);
} catch (MessagingException ex) {
folder.open(Folder.READ_ONLY);
}
int totalMessages = folder.getMessageCount();
if (totalMessages == 0) {
System.out.println("Empty folder");
folder.close(false);
store.close();
System.exit(1);
}
if (verbose) {
int newMessages = folder.getNewMessageCount();
System.out.println("Total messages = " + totalMessages);
System.out.println("New messages = " + newMessages);
System.out.println("-------------------------------");
}
if (optind >= argv.length) {
// Attributes & Flags for all messages ..
Message[] msgs = folder.getMessages();
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.FLAGS);
fp.add("X-Mailer");
folder.fetch(msgs, fp);
for (int i = 0; i < msgs.length; i++) {
System.out.println("--------------------------");
System.out.println("MESSAGE #" + (i + 1) + ":");
dumpEnvelope(msgs[i]);
// dumpPart(msgs[i]);
}
} else {
while (optind < argv.length) {
int msgnum = Integer.parseInt(argv[optind++]);
System.out.println("Getting message number: " + msgnum);
Message m = null;
try {
m = folder.getMessage(msgnum);
dumpPart(m);
} catch (IndexOutOfBoundsException iex) {
System.out.println("Message number out of range");
}
}
}
folder.close(false);
store.close();
} catch (Exception ex) {
System.out.println("Oops, got exception! " + ex.getMessage());
ex.printStackTrace();
System.exit(1);
}
System.exit(0);
}
public static void dumpPart(Part p) throws Exception {
if (p instanceof Message)
dumpEnvelope((Message)p);
/** Dump input stream ..
InputStream is = p.getInputStream();
// If "is" is not already buffered, wrap a BufferedInputStream
// around it.
if (!(is instanceof BufferedInputStream))
is = new BufferedInputStream(is);
int c;
while ((c = is.read()) != -1)
System.out.write(c);
**/
String ct = p.getContentType();
try {
pr("CONTENT-TYPE: " + (new ContentType(ct)).toString());
} catch (ParseException pex) {
pr("BAD CONTENT-TYPE: " + ct);
}
String filename = p.getFileName();
if (filename != null)
pr("FILENAME: " + filename);
/*
* Using isMimeType to determine the content type avoids
* fetching the actual content data until we need it.
*/
if (p.isMimeType("text/plain")) {
pr("This is plain text");
pr("---------------------------");
if (!showStructure && !saveAttachments)
System.out.println((String)p.getContent());
} else if (p.isMimeType("multipart/*")) {
pr("This is a Multipart");
pr("---------------------------");
Multipart mp = (Multipart)p.getContent();
level++;
int count = mp.getCount();
for (int i = 0; i < count; i++)
dumpPart(mp.getBodyPart(i));
level--;
} else if (p.isMimeType("message/rfc822")) {
pr("This is a Nested Message");
pr("---------------------------");
level++;
dumpPart((Part)p.getContent());
level--;
} else {
if (!showStructure && !saveAttachments) {
/*
* If we actually want to see the data, and it's not a
* MIME type we know, fetch it and check its Java type.
*/
Object o = p.getContent();
if (o instanceof String) {
pr("This is a string");
pr("---------------------------");
System.out.println((String)o);
} else if (o instanceof InputStream) {
pr("This is just an input stream");
pr("---------------------------");
InputStream is = (InputStream)o;
int c;
while ((c = is.read()) != -1)
System.out.write(c);
} else {
pr("This is an unknown type");
pr("---------------------------");
pr(o.toString());
}
} else {
// just a separator
pr("---------------------------");
}
}
/*
* If we're saving attachments, write out anything that
* looks like an attachment into an appropriately named
* file. Don't overwrite existing files to prevent
* mistakes.
*/
if (saveAttachments && level != 0 && p instanceof MimeBodyPart &&
!p.isMimeType("multipart/*")) {
String disp = p.getDisposition();
// many mailers don't include a Content-Disposition
if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT)) {
if (filename == null)
filename = "Attachment" + attnum++;
pr("Saving attachment to file " + filename);
try {
File f = new File(filename);
if (f.exists())
// XXX - could try a series of names
throw new IOException("file exists");
((MimeBodyPart)p).saveFile(f);
} catch (IOException ex) {
pr("Failed to save attachment: " + ex);
}
pr("---------------------------");
}
}
}
public static void dumpEnvelope(Message m) throws Exception {
pr("This is the message envelope");
pr("---------------------------");
Address[] a;
// FROM
if ((a = m.getFrom()) != null) {
for (int j = 0; j < a.length; j++)
pr("FROM: " + a[j].toString());
}
// REPLY TO
if ((a = m.getReplyTo()) != null) {
for (int j = 0; j < a.length; j++)
pr("REPLY TO: " + a[j].toString());
}
// TO
if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++) {
pr("TO: " + a[j].toString());
InternetAddress ia = (InternetAddress)a[j];
if (ia.isGroup()) {
InternetAddress[] aa = ia.getGroup(false);
for (int k = 0; k < aa.length; k++)
pr(" GROUP: " + aa[k].toString());
}
}
}
// SUBJECT
pr("SUBJECT: " + m.getSubject());
// DATE
Date d = m.getSentDate();
pr("SendDate: " +
(d != null ? d.toString() : "UNKNOWN"));
// FLAGS
Flags flags = m.getFlags();
StringBuffer sb = new StringBuffer();
Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags
boolean first = true;
for (int i = 0; i < sf.length; i++) {
String s;
Flags.Flag f = sf[i];
if (f == Flags.Flag.ANSWERED)
s = "\\Answered";
else if (f == Flags.Flag.DELETED)
s = "\\Deleted";
else if (f == Flags.Flag.DRAFT)
s = "\\Draft";
else if (f == Flags.Flag.FLAGGED)
s = "\\Flagged";
else if (f == Flags.Flag.RECENT)
s = "\\Recent";
else if (f == Flags.Flag.SEEN)
s = "\\Seen";
else
continue; // skip it
if (first)
first = false;
else
sb.append(' ');
sb.append(s);
}
String[] uf = flags.getUserFlags(); // get the user flag strings
for (int i = 0; i < uf.length; i++) {
if (first)
first = false;
else
sb.append(' ');
sb.append(uf[i]);
}
pr("FLAGS: " + sb.toString());
// X-MAILER
String[] hdrs = m.getHeader("X-Mailer");
if (hdrs != null)
pr("X-Mailer: " + hdrs[0]);
else
pr("X-Mailer NOT available");
}
static String indentStr = " ";
static int level = 0;
/**
* Print a, possibly indented, string.
*/
public static void pr(String s) {
if (showStructure)
System.out.print(indentStr.substring(0, level * 2));
System.out.println(s);
}
}
The command I'm using to run is java msgshow -D -T imaps -H imap.gmail.com -U [USER] -P [PASS] and the command I'm using to compile it is javac -cp ".:./:./lib:./lib/*" msgshow.java. The javax.mail.jar is contained in the lib folder
This is some alternate code that's much shorter and gets the same errors:
import java.util.*;
import java.io.*;
import javax.mail.*;
import smtp;
import imaps;
//import java.mail.*;
//import com.sun.mail.*;
public class AccessGmail {
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
try
{
Properties prop = new Properties();
prop.load(new FileInputStream(new File("smtp.properties")));
Session session = Session.getDefaultInstance(prop, null);
String pass = scan.next();
Store store = session.getStore("imaps");
store.connect("smtp.gmail.com","shane.l.gvoice#gmail.com",pass);
Folder inbox = store.getFolder("inbox");
inbox.open(Folder.READ_ONLY);
int messageCount = inbox.getMessageCount();
System.out.println("Message Count: "+messageCount);
}
catch (FileNotFoundException e){}
catch (IOException e){}
catch(NoSuchProviderException e){}
catch(MessagingException e){}
}
}
You're not setting the CLASSPATH when you're running the program so it's not finding the javax.mail.jar file:
java -cp ".:lib/javax.mail.jar" msgshow -D -T imaps -H imap.gmail.com -U [USER] -P [PASS]
I'm trying to load an excel file(xlsx) into a Workbook Object using apache POI 3.10.
I'm receiving a java.lang.OutofMemoryError.
I'm using Java 8 with the -Xmx2g argument on the JVM.
All 4 cores(64bit System) and my RAM(4gb) are maxed out when I run the program.
The excel sheet has 43 columns and 166,961 Rows which equal 7,179,323 Cells.
I'm using Apache POIs WorkBookFactory.create(new File) because it uses less memory than using InputFileStream.
Does anyone have any ideas how to optimize memory usage or another way to create the Workbook?
Below is my test Reader class, don't judge, it's rough and includes debugging statements:
import java.io.File;
import java.io.IOException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
public class Reader {
private Workbook wb;
public Reader(File excel) {
System.out.println("CONSTRUCTOR");
wb = null;
try {
wb = WorkbookFactory.create(excel);
} catch (IOException e) {
System.out.println("IO Exception");
System.out.println(e.getMessage());
} catch (InvalidFormatException e) {
System.out.println("Invalid Format");
System.out.println(e.getMessage());
}
}
public boolean exists() { return (wb != null); }
public void print() {}
public static void main(String[] args) {
System.out.println("START PRG");
//File f = new File("oldfilename.xls");
File f = new File("filename.xlsx");
System.out.println("PATH:" + f.getAbsoluteFile());
if (!f.exists()) {
System.out.println("File does not exist.");
System.exit(0);
}
System.out.println("FILE");
Reader r = new Reader(f);
System.out.println("Reader");
r.print();
System.out.println("PRG DONE");
}
}
apparently loading a 24mb file shouldn't be causing OOM...
at first glance it appears to me, though Xmx set to 2G, there's actually not that much memory free in system. in other words OS and other processes may have taken more than 2G out of 4G of physical memory! Check available physical memory first. in case available below what's expected, try closing some other running apps/processes.
if that's not the case and there's indeed enough memory left, without profiling it's really hard to identify the real cause. use a profile tool to check JVM status, related to memory first. you may simply use jconsole (as it comes with JDK). #see this on how to activate JMX
once you are connected, check readings related to memory, specifically below memory spaces:
old gen
young gen
perm gen
monitor these spaces and see where it's struggling. I assume this is a standalone application. in case this is deployed on server (as web or services), you may consider '-XX:NewRatio' option for distributing heap spaces effectively and efficiently. #see tuning related details here.
Please confirm these before proceeding,
Is there any infinite execution in looping(for/while)
Ensure your physical storage size
Maximize buffer memory
Note
As per my understanding Apache POI will not consume that much amount of memory.
I am just a beginner, but may I ask you some questions.
Why not use XSSFWorkbook class to open XLSX file. I mean, I always use it to handle XLSX files, and this time I tried with a file(7 MB; that was the largest I could find in my computer), and it worked perfectly.
Why not use newer File API(NIO, Java 7). Again, I do not know if this will make any difference or not. But, it worked for me.
Windows 7 Ultimate | 64 bit | Intel 2nd Gen Core i3|Eclipse Juno|JDK 1.7.45|Apache POI 3.9
Path file = Paths.get("XYZABC.xlsx");
try {
XSSFWorkbook wb = new XSSFWorkbook(Files.newInputStream(file, StandardOpenOption.READ));
} catch (IOException e) {
System.out.println("Some IO Error!!!!");
}
Do, tell if it works for you or not.
Did you tried using SXSSFWorkbook? We also used Apache POI to handle relatively big XLSX files, and we also had memory problems when using plain XSSFWorkbook. Although we didn't have to read in the files, we were just writing tens of thousands of lines of informations. Using this, our memory problems got solved. You can pass an XSSFWorkbook to its constructor and the size of data you want to keep in memory.
Java 1.8
based on HSSF and XSSF Limitations
my poi version is 3.17 POI Examples
lauches my code
public class Controller {
EX stressTest;
public void fineFile() {
String stresstest = "C:\\Stresstest.xlsx";
HashMap<String, String[]> stressTestMap = new HashMap<>();
stressTestMap.put("aaaa", new String[]{"myField", "The field"});
stressTestMap.put("bbbb", new String[]{"other", "Other value"});
try {
InputStream stressTestIS = new FileInputStream(stresstest);
stressTest = new EX(stresstest, stressTestIS, stressTestMap);
} catch (IOException exp) {
}
}
public void printErr() {
if (stressTest.thereAreErrors()) {
try {
FileWriter myWriter = new FileWriter(
"C:\\logErrorsStressTest" +
(new SimpleDateFormat("ddMMyyyyHHmmss")).format(new Date()) +
".txt"
);
myWriter.write(stressTest.getBodyFileErrors());
myWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
}
}
public void createBD() {
List<OneObjectWhatever> entitiesList =
(
!stressTest.thereAreErrors()
? ((List<OneObjectWhatever>) stressTest.toListCustomerObject(OneObjectWhatever.class))
: new ArrayList<>()
);
entitiesList.forEach(entity -> {
Field[] fields = entity.getClass().getDeclaredFields();
String valueString = "";
for (Field attr : fields) {
try {
attr.setAccessible(true);
valueString += " StressTest:" + attr.getName() + ": -" + attr.get(fields) + "- ";
attr.setAccessible(true);
} catch (Exception reflectionError) {
System.out.println(reflectionError);
}
}
});
}
}
MY CODE
public class EX {
private HashMap<Integer, HashMap<Integer, String> > rows;
private List<String> errors;
private int maxColOfHeader, minColOfHeader;
private HashMap<Integer, String> header;
private HashMap<String,String[]> relationHeaderClassPropertyDescription;
private void initVariables(String name, InputStream file) {
this.rows = new HashMap();
this.header = new HashMap<>();
this.errors = new ArrayList<String>(){{add("["+name+"] empty cells in position -> ");}};
try{
InputStream is = FileMagic.prepareToCheckMagic(file);
FileMagic fm = FileMagic.valueOf(is);
is.close();
switch (fm) {
case OLE2:
XLS2CSVmra xls2csv = new XLS2CSVmra(name, 50, rows);
xls2csv.process();
System.out.println("OLE2");
break;
case OOXML:
File flatFile = new File(name);
OPCPackage p = OPCPackage.open(flatFile, PackageAccess.READ);
XLSX2CSV xlsx2csv = new XLSX2CSV(p, System.out, 50, this.rows);
xlsx2csv.process();
p.close();
System.out.println("OOXML");
break;
default:
System.out.println("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
break;
}
} catch (IOException | EncryptedDocumentException | SAXException | OpenXML4JException exp){
System.out.println(exp);
exp.printStackTrace();
}
int rowHeader = rows.keySet().stream().findFirst().get();
this.header.putAll(rows.get(rowHeader));
this.rows.remove(rowHeader);
this.minColOfHeader = this.header.keySet().stream().findFirst().get();
this.maxColOfHeader = this.header.entrySet().stream()
.mapToInt(e -> e.getKey()).max()
.orElseThrow(NoSuchElementException::new);
}
public EX(String name, InputStream file, HashMap<String,String[]> relationHeaderClassPropertyDescription_) {
this.relationHeaderClassPropertyDescription = relationHeaderClassPropertyDescription_;
initVariables(name, file);
validate();
}
private void validate(){
rows.forEach((inx,row) -> {
for(int i = minColOfHeader; i <= maxColOfHeader; i++) {
//System.out.println("r:"+inx+" c:"+i+" cr:"+(!row.containsKey(i))+" vr:"+((!row.containsKey(i)) || row.get(i).trim().isEmpty())+" ch:"+header.containsKey(i)+" vh:"+(header.containsKey(i) && (!header.get(i).trim().isEmpty()))+" val:"+(row.containsKey(i)&&!row.get(i).trim().isEmpty()?row.get(i):"empty"));
if((!row.containsKey(i)) || row.get(i).trim().isEmpty()) {
if(header.containsKey(i) && (!header.get(i).trim().isEmpty())) {
String description = getRelationHeaders(i,1);
errors.add(" ["+header.get(i)+"]{"+description+"} = fila: "+(inx+1)+" - columna: "+ CellReference.convertNumToColString(i));
// System.out.println(" fila: "+inx+" - columna: " + i + " - valor: "+ (row.get(i).isEmpty()?"empty":row.get(i)));
}
}
}
});
header.forEach((i,v)->{System.out.println("stressTestMap.put(\""+v+"\", new String[]{\"{"+i+"}\",\"Mi descripcion XD\"});");});
}
public String getBodyFileErrors()
{
return String.join(System.lineSeparator(), errors);
}
public boolean thereAreErrors() {
return errors.stream().count() > 1;
}
public<T extends Class> List<? extends Object> toListCustomerObject(T type) {
List<Object> list = new ArrayList<>();
rows.forEach((inx, row) -> {
try {
Object obj = type.newInstance();
for(int i = minColOfHeader; i <= maxColOfHeader; i++) {
if (row.containsKey(i) && !row.get(i).trim().isEmpty()) {
if (header.containsKey(i) && !header.get(i).trim().isEmpty()) {
if(relationHeaderClassPropertyDescription.containsKey(header.get(i))) {
String nameProperty = getRelationHeaders(i,0);
Field field = type.getDeclaredField(nameProperty);
try{
field.setAccessible(true);
field.set(obj, (isConvertibleTo(field.getType(),row.get(i)) ? toObject(field.getType(),row.get(i)) : defaultValue(field.getType())) );
field.setAccessible(false);
}catch (Exception fex) {
//System.out.println("113"+fex);
continue;
}
}
}
}
}
list.add(obj);
} catch (Exception ex) {
//System.out.println("123:"+ex);
}
});
return list;
}
private Object toObject( Class clazz, String value ) {
if( Boolean.class == clazz || Boolean.TYPE == clazz) return Boolean.parseBoolean( value );
if( Byte.class == clazz || Byte.TYPE == clazz) return Byte.parseByte( value );
if( Short.class == clazz || Short.TYPE == clazz) return Short.parseShort( value );
if( Integer.class == clazz || Integer.TYPE == clazz) return Integer.parseInt( value );
if( Long.class == clazz || Long.TYPE == clazz) return Long.parseLong( value );
if( Float.class == clazz || Float.TYPE == clazz) return Float.parseFloat( value );
if( Double.class == clazz || Double.TYPE == clazz) return Double.parseDouble( value );
return value;
}
private boolean isConvertibleTo( Class clazz, String value ) {
String ptn = "";
if( Boolean.class == clazz || Boolean.TYPE == clazz) ptn = ".*";
if( Byte.class == clazz || Byte.TYPE == clazz) ptn = "^\\d+$";
if( Short.class == clazz || Short.TYPE == clazz) ptn = "^\\d+$";
if( Integer.class == clazz || Integer.TYPE == clazz) ptn = "^\\d+$";
if( Long.class == clazz || Long.TYPE == clazz) ptn = "^\\d+$";
if( Float.class == clazz || Float.TYPE == clazz) ptn = "^\\d+(\\.\\d+)?$";
if( Double.class == clazz || Double.TYPE == clazz) ptn = "^\\d+(\\.\\d+)?$";
Pattern pattern = Pattern.compile(ptn, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(value);
return matcher.find();
}
private Object defaultValue( Class clazz) {
if( Boolean.class == clazz || Boolean.TYPE == clazz) return Boolean.parseBoolean( "false" );
if( Byte.class == clazz || Byte.TYPE == clazz) return Byte.parseByte( "0" );
if( Short.class == clazz || Short.TYPE == clazz) return Short.parseShort( "0" );
if( Integer.class == clazz || Integer.TYPE == clazz) return Integer.parseInt( "0" );
if( Long.class == clazz || Long.TYPE == clazz) return Long.parseLong( "0" );
if( Float.class == clazz || Float.TYPE == clazz) return Float.parseFloat( "0.0" );
if( Double.class == clazz || Double.TYPE == clazz) return Double.parseDouble( "0.0" );
return "";
}
private String getRelationHeaders(Integer columnIndexHeader, Integer TypeOrDescription /*0 - Type, 1 - Description*/) {
try {
return relationHeaderClassPropertyDescription.get(header.get(columnIndexHeader))[TypeOrDescription];
} catch (Exception e) {
}
return header.get(columnIndexHeader);
}
}
these are the modifications I made to the examples:
XLSX2CSV
public class XLSX2CSV {
/**
* Uses the XSSF Event SAX helpers to do most of the work
* of parsing the Sheet XML, and outputs the contents
* as a (basic) CSV.
*/
private class SheetToCSV implements SheetContentsHandler {
private boolean firstCellOfRow = false;
private int currentRow = -1;
private int currentCol = -1;
HashMap<Integer, String> valuesCell;
private void outputMissingRows(int number) {
for (int i=0; i<number; i++) {
for (int j=0; j<minColumns; j++) {
output.append(',');
}
output.append('\n');
}
}
#Override
public void startRow(int rowNum) {
// If there were gaps, output the missing rows
outputMissingRows(rowNum-currentRow-1);
// Prepare for this row
firstCellOfRow = true;
currentRow = rowNum;
currentCol = -1;
valuesCell = new HashMap<>();
}
#Override
public void endRow(int rowNum) {
// Ensure the minimum number of columns
for (int i = currentCol; i < minColumns; i++) {
output.append(',');
}
output.append('\n');
if (!valuesCell.isEmpty())
_rows.put(rowNum, valuesCell);
}
#Override
public void cell(String cellReference, String formattedValue,
XSSFComment comment) {
if (firstCellOfRow) {
firstCellOfRow = false;
} else {
output.append(',');
}
// gracefully handle missing CellRef here in a similar way as XSSFCell does
if (cellReference == null) {
cellReference = new CellAddress(currentRow, currentCol).formatAsString();
}
// Did we miss any cells?
int thisCol = (new CellReference(cellReference)).getCol();
int missedCols = thisCol - currentCol - 1;
for (int i = 0; i < missedCols; i++) {
output.append(',');
}
currentCol = thisCol;
if (!formattedValue.isEmpty())
valuesCell.put(thisCol, formattedValue);
// Number or string?
output.append(formattedValue);
/*try {
//noinspection ResultOfMethodCallIgnored
Double.parseDouble(formattedValue);
output.append(formattedValue);
} catch (NumberFormatException e) {
output.append('"');
output.append(formattedValue);
output.append('"');
}*/
}
#Override
public void headerFooter(String text, boolean isHeader, String tagName) {
// Skip, no headers or footers in CSV
}
}
///////////////////////////////////////
private final OPCPackage xlsxPackage;
/**
* Number of columns to read starting with leftmost
*/
private final int minColumns;
/**
* Destination for data
*/
private final PrintStream output;
public HashMap<Integer, HashMap<Integer, String>> _rows;
/**
* Creates a new XLSX -> CSV converter
*
* #param pkg The XLSX package to process
* #param output The PrintStream to output the CSV to
* #param minColumns The minimum number of columns to output, or -1 for no minimum
*/
public XLSX2CSV(OPCPackage pkg, PrintStream output, int minColumns, HashMap<Integer, HashMap<Integer, String> > __rows) {
this.xlsxPackage = pkg;
this.output = output;
this.minColumns = minColumns;
this._rows = __rows;
}
/**
* Parses and shows the content of one sheet
* using the specified styles and shared-strings tables.
*
* #param styles The table of styles that may be referenced by cells in the sheet
* #param strings The table of strings that may be referenced by cells in the sheet
* #param sheetInputStream The stream to read the sheet-data from.
* #exception java.io.IOException An IO exception from the parser,
* possibly from a byte stream or character stream
* supplied by the application.
* #throws SAXException if parsing the XML data fails.
*/
public void processSheet(
StylesTable styles,
ReadOnlySharedStringsTable strings,
SheetContentsHandler sheetHandler,
InputStream sheetInputStream) throws IOException, SAXException {
DataFormatter formatter = new DataFormatter();
InputSource sheetSource = new InputSource(sheetInputStream);
try {
XMLReader sheetParser = SAXHelper.newXMLReader();
ContentHandler handler = new XSSFSheetXMLHandler(
styles, null, strings, sheetHandler, formatter, false);
sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource);
} catch(ParserConfigurationException e) {
throw new RuntimeException("SAX parser appears to be broken - " + e.getMessage());
}
}
/**
* Initiates the processing of the XLS workbook file to CSV.
*
* #throws IOException If reading the data from the package fails.
* #throws SAXException if parsing the XML data fails.
*/
public void process() throws IOException, OpenXML4JException, SAXException {
ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(this.xlsxPackage);
XSSFReader xssfReader = new XSSFReader(this.xlsxPackage);
StylesTable styles = xssfReader.getStylesTable();
XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
int index = 0;
while (iter.hasNext()) {
InputStream stream = iter.next();
String sheetName = iter.getSheetName();
this.output.println();
this.output.println(sheetName + " [index=" + index + "]:");
processSheet(styles, strings, new SheetToCSV(), stream);
stream.close();
++index;
break;
}
}
}
XLS2CSVmra
public class XLS2CSVmra implements HSSFListener {
private int minColumns;
private POIFSFileSystem fs;
private PrintStream output;
public HashMap<Integer, HashMap<Integer, String>> _rows;
private HashMap<Integer, String> valuesCell;
private int lastRowNumber;
private int lastColumnNumber;
/** Should we output the formula, or the value it has? */
private boolean outputFormulaValues = false;
/** For parsing Formulas */
private SheetRecordCollectingListener workbookBuildingListener;
private HSSFWorkbook stubWorkbook;
// Records we pick up as we process
private SSTRecord sstRecord;
private FormatTrackingHSSFListener formatListener;
/** So we known which sheet we're on */
private int sheetIndex = -1;
private BoundSheetRecord[] orderedBSRs;
private List<BoundSheetRecord> boundSheetRecords = new ArrayList<BoundSheetRecord>();
// For handling formulas with string results
private int nextRow;
private int nextColumn;
private boolean outputNextStringRecord;
/**
* Creates a new XLS -> CSV converter
* #param fs The POIFSFileSystem to process
* #param output The PrintStream to output the CSV to
* #param minColumns The minimum number of columns to output, or -1 for no minimum
*/
public XLS2CSVmra(POIFSFileSystem fs, PrintStream output, int minColumns, HashMap<Integer, HashMap<Integer, String>> __rows) {
this.fs = fs;
this.output = output;
this.minColumns = minColumns;
this._rows = __rows;
this.valuesCell = new HashMap<>();
}
/**
* Creates a new XLS -> CSV converter
* #param filename The file to process
* #param minColumns The minimum number of columns to output, or -1 for no minimum
* #throws IOException
* #throws FileNotFoundException
*/
public XLS2CSVmra(String filename, int minColumns, HashMap<Integer, HashMap<Integer, String>> __rows) throws IOException, FileNotFoundException {
this(
new POIFSFileSystem(new FileInputStream(filename)),
System.out, minColumns,
__rows
);
}
/**
* Initiates the processing of the XLS file to CSV
*/
public void process() throws IOException {
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
formatListener = new FormatTrackingHSSFListener(listener);
HSSFEventFactory factory = new HSSFEventFactory();
HSSFRequest request = new HSSFRequest();
if(outputFormulaValues) {
request.addListenerForAllRecords(formatListener);
} else {
workbookBuildingListener = new SheetRecordCollectingListener(formatListener);
request.addListenerForAllRecords(workbookBuildingListener);
}
factory.processWorkbookEvents(request, fs);
}
/**
* Main HSSFListener method, processes events, and outputs the
* CSV as the file is processed.
*/
#Override
public void processRecord(Record record) {
if(sheetIndex>0)
return;
int thisRow = -1;
int thisColumn = -1;
String thisStr = null;
switch (record.getSid())
{
case BoundSheetRecord.sid:
if(sheetIndex==-1)
boundSheetRecords.add((BoundSheetRecord)record);
break;
case BOFRecord.sid:
BOFRecord br = (BOFRecord)record;
if(br.getType() == BOFRecord.TYPE_WORKSHEET && sheetIndex==-1) {
// Create sub workbook if required
if(workbookBuildingListener != null && stubWorkbook == null) {
stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();
}
// Output the worksheet name
// Works by ordering the BSRs by the location of
// their BOFRecords, and then knowing that we
// process BOFRecords in byte offset order
sheetIndex++;
if(orderedBSRs == null) {
orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
}
output.println();
output.println(
orderedBSRs[sheetIndex].getSheetname() +
" [" + (sheetIndex+1) + "]:"
);
}
break;
case SSTRecord.sid:
sstRecord = (SSTRecord) record;
break;
case BlankRecord.sid:
BlankRecord brec = (BlankRecord) record;
thisRow = brec.getRow();
thisColumn = brec.getColumn();
thisStr = "";
break;
case BoolErrRecord.sid:
BoolErrRecord berec = (BoolErrRecord) record;
thisRow = berec.getRow();
thisColumn = berec.getColumn();
thisStr = "";
break;
case FormulaRecord.sid:
FormulaRecord frec = (FormulaRecord) record;
thisRow = frec.getRow();
thisColumn = frec.getColumn();
if(outputFormulaValues) {
if(Double.isNaN( frec.getValue() )) {
// Formula result is a string
// This is stored in the next record
outputNextStringRecord = true;
nextRow = frec.getRow();
nextColumn = frec.getColumn();
} else {
thisStr = formatListener.formatNumberDateCell(frec);
}
} else {
thisStr = '"' +
HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression()) + '"';
}
break;
case StringRecord.sid:
if(outputNextStringRecord) {
// String for formula
StringRecord srec = (StringRecord)record;
thisStr = srec.getString();
thisRow = nextRow;
thisColumn = nextColumn;
outputNextStringRecord = false;
}
break;
case LabelRecord.sid:
LabelRecord lrec = (LabelRecord) record;
thisRow = lrec.getRow();
thisColumn = lrec.getColumn();
thisStr = '"' + lrec.getValue() + '"';
break;
case LabelSSTRecord.sid:
LabelSSTRecord lsrec = (LabelSSTRecord) record;
thisRow = lsrec.getRow();
thisColumn = lsrec.getColumn();
if(sstRecord == null) {
thisStr = '"' + "(No SST Record, can't identify string)" + '"';
} else {
thisStr = '"' + sstRecord.getString(lsrec.getSSTIndex()).toString() + '"';
}
break;
case NoteRecord.sid:
NoteRecord nrec = (NoteRecord) record;
thisRow = nrec.getRow();
thisColumn = nrec.getColumn();
// TODO: Find object to match nrec.getShapeId()
thisStr = '"' + "(TODO)" + '"';
break;
case NumberRecord.sid:
NumberRecord numrec = (NumberRecord) record;
thisRow = numrec.getRow();
thisColumn = numrec.getColumn();
// Format
thisStr = formatListener.formatNumberDateCell(numrec);
break;
case RKRecord.sid:
RKRecord rkrec = (RKRecord) record;
thisRow = rkrec.getRow();
thisColumn = rkrec.getColumn();
thisStr = '"' + "(TODO)" + '"';
break;
default:
break;
}
// Handle new row
if(thisRow != -1 && thisRow != lastRowNumber) {
lastColumnNumber = -1;
}
// Handle missing column
if(record instanceof MissingCellDummyRecord) {
MissingCellDummyRecord mc = (MissingCellDummyRecord)record;
thisRow = mc.getRow();
thisColumn = mc.getColumn();
thisStr = "";
}
// If we got something to print out, do so
if(thisStr != null) {
if (thisColumn > 0) {
output.print(',');
}
if (!thisStr.isEmpty())
valuesCell.put(thisColumn, thisStr);
output.print(thisStr);
}
// Update column and row count
if(thisRow > -1)
lastRowNumber = thisRow;
if(thisColumn > -1)
lastColumnNumber = thisColumn;
// Handle end of row
if(record instanceof LastCellOfRowDummyRecord) {
// Print out any missing commas if needed
if(minColumns > 0) {
// Columns are 0 based
if(lastColumnNumber == -1) { lastColumnNumber = 0; }
for(int i=lastColumnNumber; i<(minColumns); i++) {
output.print(',');
}
}
// We're onto a new row
lastColumnNumber = -1;
// End the row
output.println();
if(!valuesCell.isEmpty()) {
HashMap<Integer, String> newRow = new HashMap<>();
valuesCell.forEach((inx,vStr) -> {
newRow.put(inx, vStr);
});
_rows.put(lastRowNumber, newRow);
valuesCell = new HashMap<>();
}
}
}
}
This code gets the file name, but I want to get the file path:
private List <String> checkFiles(FTPClient clients){
List <String> it = new ArrayList <String>();
try {
FTPFile[] ftpFiles = clients.listFiles();
int length = ftpFiles.length;
for (int i = 0; i < length; i++) {
String name = ftpFiles[i].getName();
Calendar date = ftpFiles[i].getTimestamp();
Log.v("aasd", name );
it.add (name);
}
} catch(Exception e) {
e.printStackTrace();
}
return it ;
}
The path is in the client, not the files.
String path = clients.printWorkingDirectory()
if you want specific path
client.changeWorkingDirectory(PathName) eg client.changeWorkingDirectory(folder1/folder2) where folder 2 is inside folder 1
System.out.println(client.printWorkingDirectory)
printWorkingDirectory gives the current path
Below code finds that all files path in any folder on ftp server.
ftpPath is likes that "ftpserver/folder". List contains paths of all files in folder.
public List<string> GetFilesPath(string ftpPath)
{
FtpWebRequest request;
string FtpServerPath = ftpPath;
List<string> filePathList=new List<string>();
try
{
request = WebRequest.Create(new Uri(FtpServerPath)) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.UseBinary = true;
request.UsePassive = true;
request.KeepAlive = true;
request.Credentials = new NetworkCredential("ftpuser", "ftpPassword");
request.ConnectionGroupName = "group";
Stream rs = (Stream)request.GetResponse().GetResponseStream();
StreamReader sr = new StreamReader(rs);
string strList = sr.ReadToEnd();
string[] lines = null;
if (strList.Contains("\r\n"))
{
lines = strList.Split(new string[] { "\r\n" }, StringSplitOptions.None);
}
else if (strList.Contains("\n"))
{
lines = strList.Split(new string[] { "\n" }, StringSplitOptions.None);
}
if (lines == null || lines.Length == 0)
return null;
else{
foreach (string line in lines)
{
if (line.Length == 0)
continue;
int x=line.LastIndexOf(' ');
int len = line.Length;
var str = line.Substring( (x+1), (len - x - 1));
var filePath = FtpServerPath+"/"+str;
filePathList.Add(filePath);
}
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
I'm currently trying to create a method that merges several ZipFiles into one big. Therefore I created a method that takes a output file and a list of InputStreams.
These InputStreams are later transformed into ZipInputStreams. That works fine!
But I have trouble when a file has already been added to the archive. At this point I need to override the entry already added (InputStreams with a higher index (lower in the list) should override the files from streams with a lower index). I also know how to do that: I just do not add the entry if a archive that would need to override it.
But the problem is how could I check if a entry is contained in a ZipInputStream so I can skip the addition of the entry for the current stream?
My code so far:
public static void makeNewZipFromInputStreamList(File outputFile,
ArrayList<InputStream> inputStreamList,
ArrayList<String> includeList, ArrayList<String> excludeList)
throws IOException, IllegalArgumentException {
final int sizeOfLists[] = new int[] { inputStreamList.size(),
includeList.size(), excludeList.size() };
if ((sizeOfLists[0] != sizeOfLists[1])
|| (sizeOfLists[0] != sizeOfLists[2])
|| (sizeOfLists[1] != sizeOfLists[2]))
throw new IllegalArgumentException(
"The ArrayLists do not have the same size ("
+ sizeOfLists[0] + ", " + sizeOfLists[1] + ", "
+ sizeOfLists[2] + ")");
final ZipOutputStream zipOutputFile = new ZipOutputStream(
new FileOutputStream(outputFile));
final int size = sizeOfLists[0];
InputStream inputStreamTempArray[] = inputStreamList
.toArray(new InputStream[size]);
String includeArray[] = includeList.toArray(new String[size]);
String excludeArray[] = excludeList.toArray(new String[size]);
int i, j;
ZipInputStream stream, streamTmp;
ZipInputStream inputStreamArray[] = new ZipInputStream[size];
String include, exclude, fileName;
ZipEntry entry;
for (i = 0; i < size; i++) {
inputStreamArray[i] = new ZipInputStream(inputStreamTempArray[i]);
if (includeArray[i] == null) {
includeArray[i] = "";
}
if (excludeArray[i] == null) {
excludeArray[i] = "";
}
}
for (i = 0; i < size; i++) {
while ((entry = inputStreamArray[i].getNextEntry()) != null) {
fileName = entry.getName();
for (j = i + 1; j < size; j++) {
// Check if the entry exists in the following archives (Then skip this entry)
}
if (fileName.matches(includeArray[i]) || !fileName.matches(excludeArray[i])) {
zipOutputFile.putNextEntry(entry);
if (!entry.isDirectory()) {
copyStream(inputStreamArray[i], zipOutputFile, false, false);
}
}
}
inputStreamArray[i].close();
}
zipOutputFile.close();
}
copyStream:
private static boolean copyStream(final InputStream is,
final OutputStream os, boolean closeInputStream,
boolean closeOutputStream) {
try {
final byte[] buf = new byte[1024];
int len = 0;
while ((len = is.read(buf)) > 0) {
os.write(buf, 0, len);
}
if (closeInputStream) {
is.close();
}
if (closeOutputStream) {
os.close();
}
return true;
} catch (final IOException e) {
e.printStackTrace();
}
return false;
}
EDIT:
I had the idea to just append the entries the other way round meaning starting from the end of the list and if a entry is already put it is just going to skip.
When I'm doing this I get a really weird error:
java.util.zip.ZipException: invalid entry compressed size (expected 1506 but got 1507 bytes)
at java.util.zip.ZipOutputStream.closeEntry(Unknown Source)
at java.util.zip.ZipOutputStream.putNextEntry(Unknown Source)
at io.brainstone.github.installer.FileUtils.makeNewZipFromInputStreamList(FileUtils.java:304)
at io.brainstone.github.installer.Main.startInstalling(Main.java:224)
at io.brainstone.github.installer.Window$3$1.run(Window.java:183)
This is my current code:
public static void makeNewZipFromInputStreamList(File outputFile,
ArrayList<InputStream> inputStreamList,
ArrayList<String> includeList, ArrayList<String> excludeList)
throws IOException, IllegalArgumentException {
final int sizeOfLists[] = new int[] { inputStreamList.size(),
includeList.size(), excludeList.size() };
if ((sizeOfLists[0] != sizeOfLists[1])
|| (sizeOfLists[0] != sizeOfLists[2])
|| (sizeOfLists[1] != sizeOfLists[2]))
throw new IllegalArgumentException(
"The ArrayLists do not have the same size ("
+ sizeOfLists[0] + ", " + sizeOfLists[1] + ", "
+ sizeOfLists[2] + ")");
final ZipOutputStream zipOutputFile = new ZipOutputStream(
new FileOutputStream(outputFile));
final int size = sizeOfLists[0];
final InputStream inputStreamTempArray[] = inputStreamList
.toArray(new InputStream[size]);
final String includeArray[] = includeList.toArray(new String[size]);
final String excludeArray[] = excludeList.toArray(new String[size]);
final ZipInputStream inputStreamArray[] = new ZipInputStream[size];
HashMap<String, Object[]> tmp;
int i, j;
String fileName;
ZipEntry entry;
for (i = size - 1; i >= 0; i--) {
System.out.println(i);
inputStreamArray[i] = new ZipInputStream(inputStreamTempArray[i]);
if (includeArray[i] == null) {
includeArray[i] = "";
}
if (excludeArray[i] == null) {
excludeArray[i] = "";
}
while ((entry = inputStreamArray[i].getNextEntry()) != null) {
fileName = entry.getName();
if (fileName.matches(includeArray[i])
|| !fileName.matches(excludeArray[i])) {
// Here is where I would check if a entry is already put.
// Probably just by catching the exception thrown in this
// case
zipOutputFile.putNextEntry(entry);
if (!entry.isDirectory()) {
copyStream(inputStreamArray[i], zipOutputFile, false,
false);
}
}
}
inputStreamArray[i].close();
}
zipOutputFile.close();
}
Hold a map from fileName to entry.
Iterate over all entries in all input streams and put the entries in the map, mapped by file name. Last entry will always override previous. When you finish you have only all highest-indexed entries per file name.
Iterate over the map's entries and put them to zipOutputFile.
// (1) here all entries will be stored, overriding low-indexed with high-indexed
final Map<String, ZipEntry> fileNameToZipEntry = new HashMap<String, ZipEntry>();
// (2) Iterate over all entries and store in map, overriding low-indexed
for (i = 0; i < size; i++) {
while ((entry = inputStreamArray[i].getNextEntry()) != null) {
fileName = entry.getName();
fileNameToZipEntry.put(fileName, entry);
}
inputStreamArray[i].close();
}
// (3) Iterating the map that holds only the entries required for zipOutputFile
int j = 0;
for ( Set<Map.Entry<String, ZipEntry>> mapEntry : fileNameToZipEntry.entrySet() ) {
if (fileName.matches(includeArray[j]) || !fileName.matches(excludeArray[j])) {
zipOutputFile.putNextEntry(entry);
if (!entry.isDirectory()) {
copyStream(inputStreamArray[j], zipOutputFile, false, false);
}
}
j++;
}
The simplest way to solve this is iterating backwards through the ArrayLists.
public static void makeNewZipFromInputStreamList(File outputFile,
ArrayList<InputStream> inputStreamList,
ArrayList<String> includeList, ArrayList<String> excludeList)
throws IOException, IllegalArgumentException {
final int sizeOfLists[] = new int[] { inputStreamList.size(),
includeList.size(), excludeList.size() };
if ((sizeOfLists[0] != sizeOfLists[1])
|| (sizeOfLists[0] != sizeOfLists[2])
|| (sizeOfLists[1] != sizeOfLists[2]))
throw new IllegalArgumentException(
"The ArrayLists do not have the same size ("
+ sizeOfLists[0] + ", " + sizeOfLists[1] + ", "
+ sizeOfLists[2] + ")");
final ZipOutputStream zipOutputFile = new ZipOutputStream(
new FileOutputStream(outputFile));
final int size = sizeOfLists[0];
final InputStream inputStreamTempArray[] = inputStreamList
.toArray(new InputStream[size]);
final String includeArray[] = includeList.toArray(new String[size]);
final String excludeArray[] = excludeList.toArray(new String[size]);
final ZipInputStream inputStreamArray[] = new ZipInputStream[size];
HashMap<String, Object[]> tmp;
int i, j;
String fileName;
ZipEntry entry;
for (i = size - 1; i >= 0; i--) {
inputStreamArray[i] = new ZipInputStream(inputStreamTempArray[i]);
if (includeArray[i] == null) {
includeArray[i] = "";
}
if (excludeArray[i] == null) {
excludeArray[i] = "";
}
while ((entry = inputStreamArray[i].getNextEntry()) != null) {
fileName = entry.getName();
if (fileName.matches(includeArray[i])
|| !fileName.matches(excludeArray[i])) {
try {
zipOutputFile.putNextEntry(entry);
if (!entry.isDirectory()) {
copyStream(inputStreamArray[i], zipOutputFile,
false, false);
}
} catch (ZipException ex) {
if (!ex.getMessage()
.matches("duplicate entry: .*\\..*")) {
throw new RuntimeException(
"Unexpected " + ex.getClass() + " (\""
+ ex.getMessage()
+ "\")\n(only duplicate entry execptions are expected!)",
ex);
}
}
}
}
inputStreamArray[i].close();
}
zipOutputFile.close();
}
But thank you anyways!