How to discover a File's creation time with Java? - java

Is there an easy way to discover a File's creation time with Java? The File class only has a method to get the "last modified" time. According to some resources I found on Google, the File class doesn't provide a getCreationTime() method because not all file systems support the idea of a creation time.
The only working solution I found involes shelling out the the command line and executing the "dir" command, which looks like it outputs the file's creation time. I guess this works, I only need to support Windows, but it seems very error prone to me.
Are there any third party libraries that provide the info I need?
Update: In the end, I don't think it's worth it for me to buy the third party library, but their API does seem pretty good so it's probably a good choice for anyone else that has this problem.

With the release of Java 7 there is a built-in way to do this:
Path path = Paths.get("path/to/file");
BasicFileAttributes attributes = Files.readAttributes(path, BasicFileAttributes.class);
FileTime creationTime = attributes.creationTime();
It is important to note that not all operating systems provide this information. I believe in those instances this returns the mtime which is the last modified time.
Windows does provide creation time.

I've wrote a small test class some days ago, wish it can help you:
// Get/Set windows file CreationTime/LastWriteTime/LastAccessTime
// Test with jna-3.2.7
// [http://maclife.net/wiki/index.php?title=Java_get_and_set_windows_system_file_creation_time_via_JNA_(Java_Native_Access)][1]
import java.io.*;
import java.nio.*;
import java.util.Date;
// Java Native Access library: jna.dev.java.net
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.*;
import com.sun.jna.platform.win32.*;
public class WindowsFileTime
{
public static final int GENERIC_READ = 0x80000000;
//public static final int GENERIC_WRITE = 0x40000000; // defined in com.sun.jna.platform.win32.WinNT
public static final int GENERIC_EXECUTE = 0x20000000;
public static final int GENERIC_ALL = 0x10000000;
// defined in com.sun.jna.platform.win32.WinNT
//public static final int CREATE_NEW = 1;
//public static final int CREATE_ALWAYS = 2;
//public static final int OPEN_EXISTING = 3;
//public static final int OPEN_ALWAYS = 4;
//public static final int TRUNCATE_EXISTING = 5;
public interface MoreKernel32 extends Kernel32
{
static final MoreKernel32 instance = (MoreKernel32)Native.loadLibrary ("kernel32", MoreKernel32.class, W32APIOptions.DEFAULT_OPTIONS);
boolean GetFileTime (WinNT.HANDLE hFile, WinBase.FILETIME lpCreationTime, WinBase.FILETIME lpLastAccessTime, WinBase.FILETIME lpLastWriteTime);
boolean SetFileTime (WinNT.HANDLE hFile, final WinBase.FILETIME lpCreationTime, final WinBase.FILETIME lpLastAccessTime, final WinBase.FILETIME lpLastWriteTime);
}
static MoreKernel32 win32 = MoreKernel32.instance;
//static Kernel32 _win32 = (Kernel32)win32;
static WinBase.FILETIME _creationTime = new WinBase.FILETIME ();
static WinBase.FILETIME _lastWriteTime = new WinBase.FILETIME ();
static WinBase.FILETIME _lastAccessTime = new WinBase.FILETIME ();
static boolean GetFileTime (String sFileName, Date creationTime, Date lastWriteTime, Date lastAccessTime)
{
WinNT.HANDLE hFile = OpenFile (sFileName, GENERIC_READ); // may be WinNT.GENERIC_READ in future jna version.
if (hFile == WinBase.INVALID_HANDLE_VALUE) return false;
boolean rc = win32.GetFileTime (hFile, _creationTime, _lastAccessTime, _lastWriteTime);
if (rc)
{
if (creationTime != null) creationTime.setTime (_creationTime.toLong());
if (lastAccessTime != null) lastAccessTime.setTime (_lastAccessTime.toLong());
if (lastWriteTime != null) lastWriteTime.setTime (_lastWriteTime.toLong());
}
else
{
int iLastError = win32.GetLastError();
System.out.print ("获取文件时间失败,错误码:" + iLastError + " " + GetWindowsSystemErrorMessage (iLastError));
}
win32.CloseHandle (hFile);
return rc;
}
static boolean SetFileTime (String sFileName, final Date creationTime, final Date lastWriteTime, final Date lastAccessTime)
{
WinNT.HANDLE hFile = OpenFile (sFileName, WinNT.GENERIC_WRITE);
if (hFile == WinBase.INVALID_HANDLE_VALUE) return false;
ConvertDateToFILETIME (creationTime, _creationTime);
ConvertDateToFILETIME (lastWriteTime, _lastWriteTime);
ConvertDateToFILETIME (lastAccessTime, _lastAccessTime);
//System.out.println ("creationTime: " + creationTime);
//System.out.println ("lastWriteTime: " + lastWriteTime);
//System.out.println ("lastAccessTime: " + lastAccessTime);
//System.out.println ("_creationTime: " + _creationTime);
//System.out.println ("_lastWriteTime: " + _lastWriteTime);
//System.out.println ("_lastAccessTime: " + _lastAccessTime);
boolean rc = win32.SetFileTime (hFile, creationTime==null?null:_creationTime, lastAccessTime==null?null:_lastAccessTime, lastWriteTime==null?null:_lastWriteTime);
if (! rc)
{
int iLastError = win32.GetLastError();
System.out.print ("设置文件时间失败,错误码:" + iLastError + " " + GetWindowsSystemErrorMessage (iLastError));
}
win32.CloseHandle (hFile);
return rc;
}
static void ConvertDateToFILETIME (Date date, WinBase.FILETIME ft)
{
if (ft != null)
{
long iFileTime = 0;
if (date != null)
{
iFileTime = WinBase.FILETIME.dateToFileTime (date);
ft.dwHighDateTime = (int)((iFileTime >> 32) & 0xFFFFFFFFL);
ft.dwLowDateTime = (int)(iFileTime & 0xFFFFFFFFL);
}
else
{
ft.dwHighDateTime = 0;
ft.dwLowDateTime = 0;
}
}
}
static WinNT.HANDLE OpenFile (String sFileName, int dwDesiredAccess)
{
WinNT.HANDLE hFile = win32.CreateFile (
sFileName,
dwDesiredAccess,
0,
null,
WinNT.OPEN_EXISTING,
0,
null
);
if (hFile == WinBase.INVALID_HANDLE_VALUE)
{
int iLastError = win32.GetLastError();
System.out.print (" 打开文件失败,错误码:" + iLastError + " " + GetWindowsSystemErrorMessage (iLastError));
}
return hFile;
}
static String GetWindowsSystemErrorMessage (int iError)
{
char[] buf = new char[255];
CharBuffer bb = CharBuffer.wrap (buf);
//bb.clear ();
//PointerByReference pMsgBuf = new PointerByReference ();
int iChar = win32.FormatMessage (
WinBase.FORMAT_MESSAGE_FROM_SYSTEM
//| WinBase.FORMAT_MESSAGE_IGNORE_INSERTS
//|WinBase.FORMAT_MESSAGE_ALLOCATE_BUFFER
,
null,
iError,
0x0804,
bb, buf.length,
//pMsgBuf, 0,
null
);
//for (int i=0; i<iChar; i++)
//{
// System.out.print (" ");
// System.out.print (String.format("%02X", buf[i]&0xFFFF));
//}
bb.limit (iChar);
//System.out.print (bb);
//System.out.print (pMsgBuf.getValue().getString(0));
//win32.LocalFree (pMsgBuf.getValue());
return bb.toString ();
}
public static void main (String[] args) throws Exception
{
if (args.length == 0)
{
System.out.println ("获取 Windows 的文件时间(创建时间、最后修改时间、最后访问时间)");
System.out.println ("用法:");
System.out.println (" java -cp .;..;jna.jar;platform.jar WindowsFileTime [文件名1] [文件名2]...");
return;
}
boolean rc;
java.sql.Timestamp ct = new java.sql.Timestamp(0);
java.sql.Timestamp wt = new java.sql.Timestamp(0);
java.sql.Timestamp at = new java.sql.Timestamp(0);
for (String sFileName : args)
{
System.out.println ("文件 " + sFileName);
rc = GetFileTime (sFileName, ct, wt, at);
if (rc)
{
System.out.println (" 创建时间:" + ct);
System.out.println (" 修改时间:" + wt);
System.out.println (" 访问时间:" + at);
}
else
{
//System.out.println ("GetFileTime 失败");
}
//wt.setTime (System.currentTimeMillis());
wt = java.sql.Timestamp.valueOf("2010-07-23 00:00:00");
rc = SetFileTime (sFileName, null, wt, null);
if (rc)
{
System.out.println ("SetFileTime (最后修改时间) 成功");
}
else
{
//System.out.println ("SetFileTime 失败");
}
}
}
}

I've been investigating this myself, but I need something that will work across Windows/*nix platforms.
One SO post includes some links to Posix JNI implementations.
JNA-POSIX
POSIX for Java
In particular, JNA-POSIX implements methods for getting file stats with implementations for Windows, BSD, Solaris, Linux and OSX.
All in all it looks very promising, so I'll be trying it out on my own project very soon.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class CreateDateInJava {
public static void main(String args[]) {
try {
// get runtime environment and execute child process
Runtime systemShell = Runtime.getRuntime();
BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter filename: ");
String fname = (String) br1.readLine();
Process output = systemShell.exec("cmd /c dir \"" + fname + "\" /tc");
System.out.println(output);
// open reader to get output from process
BufferedReader br = new BufferedReader(new InputStreamReader(output.getInputStream()));
String out = "";
String line = null;
int step = 1;
while ((line = br.readLine()) != null) {
if (step == 6) {
out = line;
}
step++;
}
// display process output
try {
out = out.replaceAll(" ", "");
System.out.println("CreationDate: " + out.substring(0, 10));
System.out.println("CreationTime: " + out.substring(10, 16) + "m");
} catch (StringIndexOutOfBoundsException se) {
System.out.println("File not found");
}
} catch (IOException ioe) {
System.err.println(ioe);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
/**
D:\Foldername\Filename.Extension
Ex:
Enter Filename :
D:\Kamal\Test.txt
CreationDate: 02/14/2011
CreationTime: 12:59Pm
*/

The javaxt-core library includes a File class that can be used to retrieve file attributes, including the creation time. Example:
javaxt.io.File file = new javaxt.io.File("/temp/file.txt");
System.out.println("Created: " + file.getCreationTime());
System.out.println("Accessed: " + file.getLastAccessTime());
System.out.println("Modified: " + file.getLastModifiedTime());
Works with Java 1.5 and up.

I like the answer on jGuru that lists the option of using JNI to get the answer. This might prove to be faster than shelling out and you may encounter other situations such as this that need to be implemented specifically for windows.
Also, if you ever need to port to a different platform, then you can port your library as well and just have it return -1 for the answer to this question on *ix.

This is a basic example in Java, using BasicFileAttributes class:
Path path = Paths.get("C:\\Users\\jorgesys\\workspaceJava\\myfile.txt");
BasicFileAttributes attr;
try {
attr = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("File creation time: " + attr.creationTime());
} catch (IOException e) {
System.out.println("oops un error! " + e.getMessage());
}

Related

How to overwrite integer at specific part of text file?

I have a textfile called "BookDetails.txt"
It is formatted in Book Title, Author, Publisher, Branch Call Number, and # of Copies like so:
1984 : George Orwell : Penguin : FIC Orw : 23
In my program, I am trying to overwrite the number of copies from 23 to 22 (decrementing by one essentially) when a patron checks out the specific book
public class CheckOutDialog extends javax.swing.JDialog {
private static final DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
ArrayList<CheckOut> checkOuts = new ArrayList<CheckOut>();
String bookTitle;
int numberOfCopies;
/**
* Creates new form CheckOutDialog
*/
public CheckOutDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
Date currentDate = new Date();
jTextFieldDate.setText(df.format(currentDate));
}
private void jButtonCheckOutActionPerformed(java.awt.event.ActionEvent evt) {
String firstName = jTextFieldFirstName.getText();
String lastName = jTextFieldLastName.getText();
bookTitle = jTextFieldBookTitle.getText();
String checkOutDate = jTextFieldDate.getText();
CheckOut checkOutInfo = new CheckOut(firstName, lastName, bookTitle, checkOutDate);
checkOuts.add(checkOutInfo);
CheckOutCopy();
}
public void CheckOutCopy() //This method checks for book and num of copies
{
try {
File f = new File("BookDetails.txt");
Scanner fileRead = new Scanner(f);
boolean foundTitle = false;
fileRead.nextLine();
while(fileRead.hasNextLine())
{
String textLine = fileRead.nextLine();
String[] bookInfo = textLine.split(" : ");
String tempBookTitle = bookInfo[0];
numberOfCopies = Integer.parseInt(bookInfo[4]);
if(tempBookTitle.trim().equals(bookTitle))
{
foundTitle = true;
break;
}
}
if(foundTitle && numberOfCopies > 0)
{
OverwriteCopies();
WriteCheckOut();
this.setVisible(false);
}
else if(numberOfCopies == 0)
{
if(JOptionPane.showConfirmDialog(null, "Would you like to add the patron to the queue?", "No copies available", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
{
AddPatronQueue();
}
else
{
JOptionPane.getRootFrame().dispose();
}
}
else
{
JOptionPanes.messageBox("Book was not found in Library Catalog", "Check Out Error");
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
private void OverwriteCopies()
{
numberOfCopies--;
//Unsure how to proceed from here
}
private void WriteCheckOut()
{
WriteFile wf = new WriteFile("CheckOutDetails.txt");
for(int i = 0; i < checkOuts.size(); i++)
{
CheckOut c = checkOuts.get(i);
String checkOutDetails = c.getFirstName() + " : " + c.getLastName() + " : " + c.getBookTitle() + " : " + c.getCheckOutDate();
wf.write(checkOutDetails);
}
wf.close();
}
My program is successful in finding a specific book and its number of copies (and it produces the JOptionPane if it has 0 copies left). However, I am unsure of how I can overwrite and update that specific element within the text file. I have done some research and it seems that RandomAccessFile may be one possible option. Is the RAF the viable solution to my problem or is there another option that I can take?

Exception when trying to instrument source code by WALA: java.lang.ClassFormatError: StackMapTable format error: wrong attribute size

I have a simple program like this:
package tests;
import java.util.Scanner;
public class TestSum {
public static void main(String[] args) {
int sum = 0;
System.out.print("Please enter starting i: ");
int i = new Scanner(System.in).nextInt();
while ( i < 11 ) {
sum = sum + i;
i = i + 1;
}
System.out.println("sum = " + sum);
System.out.println("Ending i = " + i);
}
}
I built this into a jar file and I want to use WALA to add more instrumented source code to count the number of loop execution for dynamic analysis purpose.
This is what I have done by using Wala, most of the stuffs is taken from this example Wala Bench Example
import com.ibm.wala.shrikeBT.*;
import com.ibm.wala.shrikeBT.analysis.Verifier;
import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder;
import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter;
import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter;
import com.ibm.wala.shrikeCT.ClassWriter;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintStream;
import java.io.Writer;
/**
* Created by quocnghi on 2/2/17.
*/
public class InstrumentedTest {
private final static boolean disasm = true;
private final static boolean verify = true;
private static OfflineInstrumenter instrumenter = new OfflineInstrumenter(true);
public static void main(String[] args) throws Exception {
for (int i = 0; i < 1; i++) {
Writer w = new BufferedWriter(new FileWriter("report", false));
args = instrumenter.parseStandardArgs(args);
instrumenter.setPassUnmodifiedClasses(true);
instrumenter.beginTraversal();
ClassInstrumenter ci;
while ((ci = instrumenter.nextClass()) != null) {
doClass(ci, w);
}
instrumenter.close();
}
}
static final String fieldName = "_Bench_enable_trace";
// Keep these commonly used instructions around
static final Instruction getSysOut = Util.makeGet(System.class, "out");
static final Instruction callPrintln = Util.makeInvoke(PrintStream.class, "println", new Class[]{String.class});
private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception {
final String className = ci.getReader().getName();
System.out.println("Class name : " + className);
w.write("Class: " + className + "\n");
w.flush();
for (int m = 0; m < ci.getReader().getMethodCount(); m++) {
MethodData d = ci.visitMethod(m);
System.out.println(d.getName());
// d could be null, e.g., if the method is abstract or native
if (d != null) {
w.write("Instrumenting " + ci.getReader().getMethodName(m) + " " + ci.getReader().getMethodType(m) + ":\n");
w.flush();
if (disasm) {
w.write("Initial ShrikeBT code:\n");
(new Disassembler(d)).disassembleTo(w);
w.flush();
}
if (verify) {
Verifier v = new Verifier(d);
v.verify();
}
MethodEditor methodEditor = new MethodEditor(d);
methodEditor.beginPass();
final int noTraceLabel = methodEditor.allocateLabel();
IInstruction[] instr = methodEditor.getInstructions();
final String msg0 = "Loop called at " + Util.makeClass("L" + ci.getReader().getName() + ";") + "."
+ ci.getReader().getMethodName(m);
int i = 0;
for (IInstruction in : instr) {
if (in instanceof ConditionalBranchInstruction) {
int b = i;
methodEditor.insertBefore(i, new MethodEditor.Patch() {
#Override
public void emitTo(MethodEditor.Output w) {
w.emit(getSysOut);
w.emit(ConstantInstruction.makeString(msg0));
w.emit(callPrintln);
w.emitLabel(noTraceLabel);
}
});
}
i++;
System.out.println(in.toString());
}
methodEditor.applyPatches();
if (disasm) {
w.write("Final ShrikeBT code:\n");
(new Disassembler(d)).disassembleTo(w);
w.flush();
}
}
}
ClassWriter cw = ci.emitClass();
instrumenter.outputModifiedClass(ci, cw);
}
}
I expect that after adding more instrumented code, the program should become like this, which add a line System.out.println in the loop :
package tests;
import java.util.Scanner;
public class TestSum {
public static void main(String[] args) {
int sum = 0;
System.out.print("Please enter starting i: ");
int i = new Scanner(System.in).nextInt();
while ( i < 11 ) {
sum = sum + i;
i = i + 1;
System.out.println("One count for this loop");
}
System.out.println("sum = " + sum);
System.out.println("Ending i = " + i);
}
}
But I got this error :
java.lang.ClassFormatError: StackMapTable format error: wrong attribute size
WALA does have StackMapTable support, but perhaps something is broken. I suggest filing an issue.

Sorting an array of filenames containing strings with numbers

For my project I need to download a zip file from an FTP server, which releases a new zip about 13 times a year. I need to download the latest file following the server's naming convention:
Prefix + release number (one or two digits) + year (two digits) + suffix + ".zip"
for instance:
ALFP1016F.zip
The prefix will always be the same (ALFP) and the suffix either F or P (stands for "full" or "partial"; I need only the files ending with suffix F). On top of that, there are several other files in the directory I need to ignore because they have different prefixes. Then, I need to get the most recent file in the array following this priority order:
Most recent year. Of course '99 should not be seen as the most recent year.
Most recent release number
For instance, if I have this listing of filenames (full server directory):
1stpage712.pdf
1stpage914.pdf
ALFP1015F.zip
ALFP1015P.zip
ALFP716F.zip
ALFP716P.zip
FSFP816F.zip
FSFP816P.zip
My expected output would be
ALFP716F.zip because 16 is the most recent year, and 7 the most recent release number from that year
.
Here's what I've done so far:
//necessary imports
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
//initialize FTP client
ftpClient = new FTPClient();
try {
//connect to server
ftpClient.connect(server, port);
ftpClient.login(username, password);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//list all names from server
String[] filenames = ftpClient.listNames();
//return expected file name
String expectedFileName = returnMostRecent(filenames);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
System.out.println("Disconnected from server");
}
} catch (IOException ex) { ex.printStackTrace(); }
}
I have done a miserable attempt at writing the returnMostRecent(String[]) method, but ended up with an unintelligible mess not worth being posted here.
How can I sort this array and effectively return the most recent file following my priority order?
If you use Java8 you can do:
String file = Arrays.stream(filenames)
.filter(s -> s.startsWith("ALFP") && s.endsWith("F.zip"))
.max(getReleaseComparator())
.orElse(null);
where release comparator is based on extracting numbers from file name and comparing them
I haven't tested this but I think it should work.
private String returnMostRecent(String[] fileNames) {
String file = null;
double version = -1;
for(String name : listNames)
{
// skip files that don't match
if (!name.matches("ALFP[0-9]*F.zip"))
continue;
// get digits only
String digits = name.replaceAll("\\D+","");
// format digits to <year>.<version>
String vstr = digits.substring(digits.length-2,digits.length()) + ".";
if (digits.length() < 4)
vstr += "0";
vstr = digits.substring(0, digits.length()-2);
double v = Double.parseDouble(vstr);
if (v > version)
{
version = v;
file = name;
}
}
return file;
}
I will suggest this approach:
final String[] filesArr = { "1stpage712.txt", "1stpage712.pdf", "1stpage914.pdf", "ALFP1015F.zip", "ALFP1015P.zip", "ALFP716F.zip",
"ALFP716P.zip", "FSFP816F.zip", "FSFP816P.zip" };
// turn the array into a list.
final List<String> filesList = new ArrayList<String>();
// add to the list only the good candidates
for (int i = 0; i < filesArr.length; i++) {
if (filesArr[i].matches("ALFP\\d+F.zip")) {
System.out.println("candidate");
filesList.add(filesArr[i]);
}
}
System.out.println(filesList);
Collections.sort(filesList, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
final SimpleDateFormat df = new SimpleDateFormat("mmyy");
// get the date of the file
final String dat1 = o1.substring(o1.indexOf("ALFP"), o1.indexOf("ALFP") + 3);
final String dat2 = o2.substring(o2.indexOf("ALFP"), o2.indexOf("ALFP") + 3);
Date date1;
Date date2;
try {
date1 = df.parse(dat1);
date2 = df.parse(dat2);
return date1.compareTo(date2);
} catch (final ParseException e) {
System.out.println("Error parsing date..");
return 0;
}
}
});
// since the sort is made by date chronologically, the 1st element is the oldest and the last element is
// the newest
System.out.println("The file is: " + filesList.get(filesList.size() - 1));
}
I will suggest this Solution :
private static String returnMostRecent(String[] fileNames)
{
int lastTwoDigits = Calendar.getInstance().get(Calendar.YEAR) % 100;
int fullFileRel = 0;
int partialFileRel = 0;
for(String myStr : fileNames)
{
if(myStr.startsWith("ALFP"))
{
System.out.println(myStr);
if(myStr.endsWith(""+lastTwoDigits+"F.zip"))
{
String temp = myStr.substring(4,myStr.length()-7);
System.out.println("temp : "+temp);
int releaseNum = Integer.parseInt(temp);
System.out.println("releaseNum : "+releaseNum);
if(releaseNum > fullFileRel)
fullFileRel = releaseNum;
}
if(myStr.endsWith(""+lastTwoDigits+"P.zip"))
{
String temp = myStr.substring(4,myStr.length()-7);
System.out.println("temp : "+temp);
int releaseNum = Integer.parseInt(temp);
System.out.println("releaseNum : "+releaseNum);
if(releaseNum > fullFileRel)
partialFileRel = releaseNum;
}
}
}
System.out.println("full Rel :"+fullFileRel);
System.out.println("partial Rel :"+partialFileRel);
if(fullFileRel > partialFileRel)
return "ALFP"+fullFileRel+""+lastTwoDigits+"F.zip";
else
return "ALFP"+partialFileRel+""+lastTwoDigits+"P.zip";
}
You can use regex and do something like this to parse out the year and version:
public static void main(String[] args)
{
int year = -1;
int version = -1;
String test = "ALFP716F.zip";
if(test.matches("ALFP\\d+F.zip"))
{
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(test);
matcher.find();
String tempString = matcher.group(0);
year = Integer.parseInt(tempString.substring((tempString.length() - 2)));
version = Integer.parseInt(tempString.substring(0, (tempString.length() - 2)));
}
System.out.println("Year: " + year + " Version: " + version);
}
Here is Java 1.5 compatible solution, AlphaNumComparator

How to read from a text-file.

I would like to know how can I check for a specific string on a line of a text file, save it in an array, and then move on to the next line of that text file.
For e.g.:
(what he is/ year edition/name/age/profession/number)
competitor 2014 joseph 21 student 20232341
competitor 2013 michael 23 engineer 23425123
As output, it would give me this:
Song Festival'2014
here are the competitors:
Joseph, student of 21 years - 20232341
Song Festival'2013
are the competitors
Michael, engineer of 23 years - 23425123
edit: java language
For this you would use a BufferedReader, you can format things in the text file using the tab (indent) which would be read from the BufferedReader as '\t' I'll write an example for you in a moment.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class StackoverflowExample {
private static final int INFORMATION_CAP = 100;
private static String[][] INFORMATION = new String[INFORMATION_CAP][INFORMATION_CAP];
public StackoverflowExample() {
String currentLine;
String[] textData;
int lineID = 0;
boolean endOfFile = false;
try {
BufferedReader reader = new BufferedReader(new FileReader("textfile.txt"));
currentLine = reader.readLine();
while(!endOfFile && currentLine != null) {
currentLine = currentLine.trim();
textData = currentLine.split("\\t");
String userType = textData[0];
String year = textData[1];
String name = textData[2];
String age = textData[3];
String profession = textData[4];
String number = textData[5];
INFORMATION[lineID] = new String[] { userType, year, name, age, profession, number };
lineID++;
currentLine = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new StackoverflowExample();
for(int i = 0; i < INFORMATION.length; i++) {
System.out.println("Type: " + INFORMATION[i][0] +
"year: " + INFORMATION[i][1] +
"name: " + INFORMATION[i][2] +
"age: " + INFORMATION[i][3] +
"profession: " + INFORMATION[i][4] +
"number: " + INFORMATION[i][5]);
}
}
}
Create a text file called "textfile.txt" in your projects main directory, and format it like this
type(tab)year(tab)name(tab)age(tab)profession(tab)number(newline)

threads for reading and writing java

i'm reading data from serial port for average interval say 1 second,and at the same time writing read data to textArea and textfile,problem is i'm not getting correct data at some time,may be because i'm doing all three process in a single program,how to do writing to text area and text file by separate thred?
this is my code:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.TooManyListenersException;
import java.util.TreeMap;
import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
import javax.swing.JOptionPane;
import com.pressure.constants.Constants;
import com.pressure.online.OnlineStartWindow;
public class SerailReader implements SerialPortEventListener {
// DECLARES INPUT STREAM TO READ SRIAL PORT
private InputStream inputStream;
// DECLARES PORT
private CommPortIdentifier port;
private SerialPort serialPort;
// DATE TO CREATE FILE NAME
private static final SimpleDateFormat SDF = new SimpleDateFormat("dd-MM-yy");
private int index = 0;
private File file;
private OnlineStartWindow onlineStartwindow;
private int[] tempIntArray = new int[233];
private int newData = 0;
private String outFolder;
private String filename = "0";
private FileWriter fileWriter;
private BufferedWriter buffOut;
private StringBuffer line;
private String packetFilename;
TreeMap<Integer, Float> channelMap = new TreeMap<Integer, Float>();
ThreadPrintsAndWrites p;
public FileWriter getFileWriter() {
return fileWriter;
}
public void setFileWriter(FileWriter fileWriter) {
this.fileWriter = fileWriter;
}
public BufferedWriter getBuffOut() {
return buffOut;
}
public void setBuffOut(BufferedWriter buffOut) {
this.buffOut = buffOut;
}
// SETTER GETTER TO OnlineStartwindow OBJECT
public OnlineStartWindow getOnlineStartwindow() {
return onlineStartwindow;
}
public void setOnlineStartwindow(OnlineStartWindow onlineStartwindow) {
this.onlineStartwindow = onlineStartwindow;
}
// SETTER GETTER TO SERIALPORT
public SerialPort getSerialPort() {
return serialPort;
}
public void setSerialPort(SerialPort serialPort) {
this.serialPort = serialPort;
}
// ********* connects to serial port ***********//
public void SerialReadmethod(OnlineStartWindow onlineStartwindow,
String outFolderPath) throws Exception {
setOnlineStartwindow(onlineStartwindow);
outFolder = outFolderPath;
// SELECTS PORT NAME SELECTED
port = CommPortIdentifier.getPortIdentifier(getOnlineStartwindow()
.getComPort());
System.out.println("port name " + port);
// CHEAK WETHER SELECTED PORT AVAILABLE OR NOT
if (port.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (port.getName().equals(getOnlineStartwindow().getComPort())) {
JOptionPane.showMessageDialog(null, "Successpully opened port",
"Online Dump", JOptionPane.INFORMATION_MESSAGE);
}
}
// OPENS SERAIL PORT
serialPort = (SerialPort) port.open("SimpleReadApp1111", 1000);
// OPENS SERIAL PORT INPUT STREAM TO READ DATA
try {
inputStream = serialPort.getInputStream();
} catch (IOException e) {
System.out.println("IO Exception");
}
// ADDS LISTNER TO SERIALPORT
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
System.out.println("Tooo many Listener exception");
}
// EVENT GENERATED WHEN DATA WILL BE AVAILABELE ON SERIALPORT
// INPUTSTREAM
serialPort.notifyOnDataAvailable(true);
try {
// SETS SELECTED BAUDRATE
int BAUDRATE = Integer.parseInt((getOnlineStartwindow()
.getBaudRate()).trim());
// SETS SELECTED DATA BITS
int DATABITS = Integer.parseInt(getOnlineStartwindow()
.getDataBits().trim());
if (DATABITS == 8) {
DATABITS = SerialPort.DATABITS_8;
} else if (DATABITS == 7) {
DATABITS = SerialPort.DATABITS_7;
} else if (DATABITS == 6) {
DATABITS = SerialPort.DATABITS_6;
} else if (DATABITS == 5) {
DATABITS = SerialPort.DATABITS_5;
}
// SETS SELECTED STOPBITS
int STOPBITS = 0;
if (getOnlineStartwindow().getStopBits() == "1") {
STOPBITS = SerialPort.STOPBITS_1;
} else if (getOnlineStartwindow().getStopBits() == "1.5") {
STOPBITS = SerialPort.STOPBITS_1_5;
} else if (getOnlineStartwindow().getStopBits() == "2") {
STOPBITS = SerialPort.STOPBITS_2;
}
// SETS SELECTED PARITY
int PARITY = 0;
if (getOnlineStartwindow().getParity() == "NONE") {
PARITY = SerialPort.PARITY_NONE;
} else if (getOnlineStartwindow().getParity() == "EVEN") {
PARITY = SerialPort.PARITY_EVEN;
} else if (getOnlineStartwindow().getParity() == "ODD") {
PARITY = SerialPort.PARITY_ODD;
}
// SETS SELECTED FLOW CONTROL
int FLOWCONTROL = 0;
if (getOnlineStartwindow().getFlowControl() == "NONE") {
FLOWCONTROL = SerialPort.FLOWCONTROL_NONE;
} else if (getOnlineStartwindow().getFlowControl() == "XON/XOFF") {
FLOWCONTROL = SerialPort.FLOWCONTROL_XONXOFF_IN;
}
serialPort
.setSerialPortParams(BAUDRATE, DATABITS, STOPBITS, PARITY);
// no handshaking or other flow control
serialPort.setFlowControlMode(FLOWCONTROL);
} catch (UnsupportedCommOperationException e) {
System.out.println("UnSupported comm operation");
}
}
// *********this method will automaticaly calls when u get data on port and
// arranges packet from start frame to end frame *************//
public void serialEvent(SerialPortEvent event) {
// switch (event.getEventType()) {
//
// case SerialPortEvent.DATA_AVAILABLE:
if(event.getEventType()==SerialPortEvent.DATA_AVAILABLE){
//dataAvailabel = inputStream.available();
// READING DATA CHARECTER BY CHARECTER
while (newData != -1) {
try {
newData = inputStream.read();
if (newData == -1) {
break;
}
if (Constants.SF == (char) newData) {
index = 0;
// System.out.println("start frame");
}
tempIntArray[index] = newData;
if (Constants.EF == (char) newData) {
selectToDispalyAndWrite(tempIntArray);
// disp(tempIntArray);
}
index++;
} catch (IOException ex) {
System.err.println(ex);
// return;
}
}
// ///////////////// completes
}
}
// DISPLYS PACKET TO TEXT AREA AND CREATES .PSI FILE
public void selectToDispalyAndWrite(int[] readBufferArray) {
if (getOnlineStartwindow().getDump().isSelected()) {
packetFilename = Integer.toString(readBufferArray[1])
+ Integer.toString(readBufferArray[2])
+ Integer.toString(readBufferArray[3]);
try {
if (getOnlineStartwindow().getFileTypeSelection() == "text") {
displayAndWriteToTextFile(readBufferArray);
} else {
displayAndWriteToExcelFile(readBufferArray);
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
printToTextArea(readBufferArray);
}
}
public void printToTextArea(int[] readBufferArray) {
int i = 0;
int portname = 0;
Float portval = 0.0f;
int len = 0;
i = 0;
writeloop: while (len != readBufferArray.length) {
// while ((char) readBufferArray[i] != Constants.EF) {
if ((char) readBufferArray[i] == Constants.SF) {
// WRITES DASH LINE TO TEXT AREA
getOnlineStartwindow()
.getTextArea()
.append(
"\r\n\r\n-----------------------------------------------------------------------\r\n");
getOnlineStartwindow().getTextArea().append(
"Time :" + readBufferArray[i + 4] + " Min "
+ readBufferArray[i + 5] + " Sec.");
getOnlineStartwindow()
.getTextArea()
.append(
"\r\n-----------------------------------------------------------------------\r\n");
}
if ((char) readBufferArray[i] == Constants.EF) {
for (Iterator<Integer> iterator = channelMap.keySet()
.iterator(); iterator.hasNext();) {
int key = iterator.next();
Float value = channelMap.get(key);
getOnlineStartwindow().getTextArea().append(
"Port_" + key + " " + value + "\r\n");
}
channelMap.clear();
break writeloop;
}
i++;
}
}
public void displayAndWriteToTextFile(int[] readBufferArray)
throws IOException {
int i = 0;
int portname = 0;
Float portval = 0.0f;
if (!(filename.equalsIgnoreCase(packetFilename))) {
filename = packetFilename;
if (buffOut != null && fileWriter != null) {
drawLine('*');
buffOut.close();
fileWriter.close();
}
// GET CURRENT DATE
Date date = new Date();
file = new File(outFolder + "\\" + SDF.format(date) + "-"
+ packetFilename + ".txt");
if (!file.exists()) {
fileWriter = new FileWriter(file, true);
buffOut = new BufferedWriter(fileWriter);
drawLine('*');
drawLine('*');
} else {
fileWriter = new FileWriter(file, true);
buffOut = new BufferedWriter(fileWriter);
}
}
// LOOP TO DISPLY ALL PORT NAME AND PRESSURE VALUES
int len = 0;
i = 0;
writeloop: while (len != readBufferArray.length) {
// while ((char) readBufferArray[i] != Constants.EF) {
if ((char) readBufferArray[i] == Constants.SF) {
// WRITES DASH LINE TO TEXT AREA
getOnlineStartwindow()
.getTextArea()
.append(
"\r\n\r\n-----------------------------------------------------------------------\r\n");
getOnlineStartwindow().getTextArea().append(
"Time :" + readBufferArray[i + 4] + " Min "
+ readBufferArray[i + 5] + " Sec.");
getOnlineStartwindow()
.getTextArea()
.append(
"\r\n-----------------------------------------------------------------------\r\n");
drawLine('-');
buffOut.write("TIME: " + readBufferArray[i + 4] + " Min "
+ readBufferArray[i + 5] + " Sec." + "\r\n\r\n");
}
if ((char) readBufferArray[i] == Constants.ST) {
portname = readBufferArray[i + 1];
portval = getFloatValue(i);
channelMap.put(portname, portval);
}
if ((char) readBufferArray[i] == Constants.EF) {
for (Iterator<Integer> iterator = channelMap.keySet()
.iterator(); iterator.hasNext();) {
int key = iterator.next();
Float value = channelMap.get(key);
getOnlineStartwindow().getTextArea().append(
"Port_" + key + " " + value + "\r\n");
}
channelMap.clear();
break writeloop;
}
i++;
}
}
}
Thanks in advance
Here an approach from a design standpoint.
Create a class type for the data. This will be a container (inherit the appropriate queue). And inside of this class as you set and get the data make sure you lock.
Create a new thread in main to start the serial port and read the messages. Pass the thread one object (your list class object). The serial port will chuck data into this list. This will be sets in the object.
You main thread (the window) will have a timer that fires and reads the data from queue. You may have to play with the timer some. You don't want it firing too often and eating all your processing time in the main window. However if it is too slow you may not be updating enough and getting messages out of the queue when they are available. This timer should get all of the data out the queue and display it.
The queue and the lock are the important part here. The queue will keep messages in order. The lock will make sure you don't try to write new data to your queue while you are in the middle of reading data.
I was under the impression that Java does not support serial port for Windows, it only does it for Solaris or Linux.
your class should implement the Runnable Interface. and create a thread that reads from the serial port in its run method.
The Main thread could do the writing part to the TextArea.
You may need to do some synchronization between the Main Thread and the Runnable so that writing to the TextArea/File only takes place after appropriate data has been read from the port.

Categories

Resources