When I try to get attatchment from POP 3 mail, I am getting them as winmail.dat, not the original attached file name. How can I get the original file name?
for (int i = 0; i < multipart.getCount(); i++)
{
BodyPart bodyPart = multipart.getBodyPart(i);
if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
//do something
}
else
{
bodyPart.getFileName(); // here only get the winmail.dat
}
}
This is part of the Exchange Settings, and sadly you going to need to extract the original contents from the WinMail.dat using JTNEF.
"The Java TNEF package is an open source code implementation of a TNEF message handler, which can be used as a command-line utility or integrated into Java-based mail applications to extract the original message content."
This is found on the JavaMail's third party tools.
As alternative and what looks simpler is POI-HMEF
Sample extraction:
public void extract(String winmailFilename, String directoryName) throws Exception {
HMEFContentsExtractor ext = new HMEFContentsExtractor(new File(winmailFilename));
File dir = new File(directoryName);
File rtf = new File(dir, "message.rtf");
if(! dir.exists()) {
throw new FileNotFoundException("Output directory " + dir.getName() + " not found");
}
System.out.println("Extracting...");
ext.extractMessageBody(rtf);
ext.extractAttachments(dir);
System.out.println("Extraction completed");
}
There is also a sample for printing the contents here.
Related
I'm new to programming and working on this project of Library System.
It uses linked lists to save details of books and members.
It has two functions that print details of all books in library and all members of library.
As I made a GUI for my project I can't print details in Frame.
So, I thought of doing it with file.
I have successfully printed everything in file but now my problem is how should I display file to user?
Like if user presses "show all books" button, it should automatically open the respective file.
I tried searching but I can't figure out what to actually search as I'm a beginner.
Any help would be much appreciated please.
UPDATE:
I tried with Desktop.getDesktop(file) and I am getting this error.
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "Book issued successfully"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.parseLong(Long.java:631)
at RunProgram.stringToLong(RunProgram.java:217)
at RunProgram.actionPerformed(RunProgram.java:196)
This is my stringToLong method
private static long stringToLong(String stringObject){
return Long.parseLong(stringObject.trim());
}
This is the method for printing details
void printBooksIssued(long cpr) throws IOException{
File file = new File("d:/work/test.txt");
System.setOut(new PrintStream(new FileOutputStream(file)));
int index = 0;
if (searchMember(cpr) == -1)
System.out.println("Member doesn't exist.");
LibMember m = membersList.get(index);
while (index < sizeMembersList() ){
if (m.getCprNum() == cpr){
System.out.println(Arrays.toString(m.getBooksIssued()));
return;
}
index++;
if (index < sizeMembersList())
m = membersList.get(index);
}
Desktop.getDesktop().open(file);
}
And this is how I called this method inside actionListener method.
case "Print details of books issued to member": {
long cprNum = stringToLong(cpr.getText());
try {
ITLib.printBooksIssued(cprNum);
}
catch (IOException e1){
fName.setText("Error. Make sure CPR number is correct and try again.");
}
}
The thing I don't understand is that the first error of numberFormatException of string "Book issued successfully is completely separate from this button and textfield. Then why is it giving error with that.
case "Issue": {
long an = stringToLong(NUM.getText());
long cpr = stringToLong(CPR.getText());
if (ITLib.issueBook(an, cpr))
NUM.setText("Book issued successfully");
else
NUM.setText("Book couldn't be issued. Try again later.");
break;
}
If you are using Java and save the files with the suffix ".txt", you can use Desktop.getDesktop().
Here is an example that will popup the default system editor for text:
File file = new File("d:/work/test.txt");
System.setOut(new PrintStream(new FileOutputStream(file)));
System.out.println("Testing 1");
System.out.println("Testing 2");
Desktop.getDesktop().open(file);
On Windows this will open notepad.exe with the "text.txt" file.
I am using App Engine application to receive emails to a specific list of email address ending with #my-app-id.appspotmail.com will be sent to your application.
Multipart multiPart = (Multipart) message.getContent();
BodyPart bp = multiPart.getBodyPart(0);
log.info("count is "+multiPart.getCount());
String attachFiles = "";
String messageContent = "";
for (int i = 0; i < multiPart.getCount(); i++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
// this part is attachment
String fileName = part.getFileName();
log.info("file name is "+fileName);
} else {
// this part may be the message content
messageContent = part.getContent().toString();
}
}
I want to store the File inside a Blob store but i did not find an API for it, It is going inside the IF loop and am able to get the attachment file name. Any help will be appreciated.
You can read all the data inside the attachment part using the MimeBodyPart.getInputStream method, but you'll need to read the data yourself and create the Blob.
Given a simple route like this
route.from("direct:foo")
.split()
.tokenize("\n")
.streaming()
.to("stream:file?fileName=target/streaming${header.count}.txt&closeOnDone=true");
which I then trigger with this
#Test
public void splitAndStreamToFile() {
StringBuilder builder = new StringBuilder();
for(int i = 0; i < 500; i++) {
builder.append(i);
builder.append("\n");
}
for(int i = 0; i < 10; i++) {
template.sendBodyAndHeader(builder.toString(), "count", i);
}
}
I get one big file that contains 10 times 500 lines, where I would have hoped to have 10 files that contain 500 lines each.
In other words, it seems that the fileName in the stream:file endpoint is not dynamic. I am wondering if this is at all possible? My google-fu turned up nothing so far.
EDIT:
With Claus' answer, I got it to work like this:
route.from("direct:foo")
.split()
.tokenize("\n")
.streaming()
.recipientList(route.simple("stream:file?fileName=target/streaming${header.count}.txt&closeOnDone=true"));
Its a dynamic to which there is an EIP pattern for:
http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
But it could be a good idea to support the file/simple language on the fileName option as the regular file component does. Fell free to log a JIRA ticket about this improvement.
Sourcecode of the StreamProducer looks like it does not support any of the expression languages of Camel yet:
private OutputStream resolveStreamFromFile() throws IOException {
String fileName = endpoint.getFileName();
ObjectHelper.notEmpty(fileName, "fileName");
LOG.debug("About to write to file: {}", fileName);
File f = new File(fileName);
// will create a new file if missing or append to existing
f.getParentFile().mkdirs();
f.createNewFile();
return new FileOutputStream(f, true);
}
See sourecode.
If you need dynamic filenames, you should take a look at the file component, which supports the file language and the CamelFileName header.
In short,
toD uri=stream:file...
will do it.
The "toD" basically translates the "simple" or "file language" before it hits the stream component code...so that works for "fileName=..."
In my app I tried to pass the file path from one activity to another activity using intent.In my receiving activity I got the file path as "null".But when I print the file in first activity it prints the path.From my second activity I attach that file to mail using Gmailsender.This was the code I tried,
private void startRecord()
{
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
try
{
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
8000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
audioRecord.startRecording();
while(recording)
{
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++)
{
dataOutputStream.writeShort(audioData[i]);
}
}
audioRecord.stop();
audioRecord.release();
dataOutputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
String audiofile;
audiofile=file.getAbsolutePath();
System.out.println("File Path::::"+audiofile);
}
Intent is,
Intent sigout=new Intent(getApplicationContext(),WeeklyendActivity.class);
sigout.putExtra("mnt/sdcard-test.pcm",audiofile);
startActivity(sigout);
In my receiving activity,
String patty=getIntent().getStringExtra("mnt/sdcard-text.pcm");
System.out.println("paathhhy frfom ::"+patty);
It prints null.Can anyone help me how to get the file path.And more thing I am not sure whether the audio would save in that file correctly?
Please anyone help me!!!Thanks in advance!
Based on your information that audioFile is a variable of type File, when you do this:
sigout.putExtra("mnt/sdcard-test.pcm",audiofile);
you are putting a File object in the extras Bundle. Then, when you try to get the extra from the Bundle you do this:
String patty=getIntent().getStringExtra("mnt/sdcard-text.pcm");
However, the object in this extra is of type File, not type String. This is why you are getting null.
If you only want to pass the name of the file, then put the extra like this:
sigout.putExtra("mnt/sdcard-test.pcm",audiofile.getAbsolutePath());
I can send attachments that have non-ascii filenames in JavaMail but I am not able to download them. I am getting java.io.FileNotFoundException specifically for those attachments whose file names contain non-ascii characters.
FYI: I am using something like messageBodyPart.setFileName(MimeUtility.encodeText(filename[i])) to encode the text and MimeUtility.decodeText(bodyPart.getFileName()) to decode the non-ascii file names
Is there a workaround for this?
EDIT
#Bill, here is part of my code that reads attachments. I have also added the properties.setProperty("mail.mime.decodeparameters", "true") and properties.setProperty("mail.mime.decodefilename", "true") properties in my code.
if (message[a].getContent() instanceof MimeMultipart) {
Multipart multipart = (Multipart) message[a].getContent();
for (int i = 0; i < multipart.getCount(); i++) {
bodyPart = multipart.getBodyPart(i);
disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equals(BodyPart.ATTACHMENT) || (disposition.equals(BodyPart.INLINE)))) {
DataHandler handler = bodyPart.getDataHandler();
String path = bodyPart.getFileName();
String[] str = path.split("/");
String fileName = str[str.length - 1];
String filePath = ReadConfigPropertiesFile.getPropertyValue("server.buildpath");
System.out.println(fileName);
File tempDir = new File(filePath + user);
if (!tempDir.exists()) {
tempDir.mkdir();
}
File saveFile = new File(tempDir + "/" + fileName);
int count = 0;
while (saveFile.exists()) {
count++;
saveFile = new File(tempDir + "/" + count + "_" + fileName);
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile));
byte[] buff = new byte[2048];
InputStream is = bodyPart.getInputStream();
int ret = 0;
while ((ret = is.read(buff)) > 0) {
bos.write(buff, 0, ret);
}
bos.close();
is.close();
//System.out.println(bodyPart.getContentType());
}else {
//display body (message) of the attachment;
//System.out.println(bodyPart.getContent().toString());
}
}
}
The above code raises the FileNotFoundException exception at BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile)) line and this is getting raised for the attachments whose file names are non-ascii characters (something like ሰላም.pdf). Every thing else works fine.
This answer taken from comment of #semytech (OP). It was hard to find it there, so I will add it as answer for more visibility. It helped me with hebrew filenames.
MimeBodyPart attachment = new MimeBodyPart();
attachment.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
You should never need to do the encoding or decoding yourself.
There are two sets of properties you can set to tell JavaMail to do the encoding/decoding for you:
mail.mime.encodefilename/mail.mime.decodefilename
mail.mime.encodeparameters/mail.mime.decodeparameters
See the javadocs for the javax.mail.internet package for details.
The first set uses a non-standard encoding technique, similar to what you're doing yourself. This works fine with some older mailers that use this technique.
The second set uses a MIME standard encoding technique. This version works with most modern mailers.
None of this explains why you're getting FileNotFoundException, but then you didn't provide enough detail to know what you're doing when you get the exception.