hxtt DBF driver locks its files - java

My web app receives archive, unpacks it to temp folder, reads data from extracted DBFs and then should kill garbage. Though it fails to kill temp folder since DBF files in it are locked. Here is a sample code:
public static void main( String a[] ) throws Exception
{
Class.forName( "com.hxtt.sql.dbf.DBFDriver" ).newInstance();
String url = "jdbc:DBF:/C:/TEMP/";
Properties properties = new Properties();
properties.setProperty( "charSet", "cp866" );
Connection con = null;
Statement st = null;
java.sql.Driver d = null;
con = DriverManager.getConnection( url, properties );
d = DriverManager.getDriver( url );
st = con.createStatement();
ResultSet rs = st.executeQuery( "SELECT * FROM 6QQQ201010" );
rs.close();
st.close();
con.close();
}
I put breakpoint past last line and 6QQQ201010.DBF is still locked. Any ideas? Or just a bug in the driver?

Add properties.setProperty( "delayedClose", "0" ); and driver would close handles imediately.

Related

Why is the file Read-Only?

I have got a Microsoft Access database in the resource folder of my Java application.
When the user clicks a button, this database is copied to the temp directory of the PC. Then I make a temporary VBS file in the same directory and execute it.
(This VBS file calls a VBA macro within the database, that deletes some records.)
However, as the macro attempts to delete the records an error is thrown stating that the database is read only.
Why does this happen?
Here is my code:
When the user clicks the button, some variables are set and then the following code is executed:
private void moveAccess() throws IOException {
String dbName = "sys_cl_imp.accdb";
String tempDbPath = System.getenv("TEMP").replace('\\', '/') + "/" + dbName;
InputStream in = ConscriptioLegere.class.getResourceAsStream("res/" + dbName);
File f = new File(tempDbPath);
Files.copy(in, f.toPath(), StandardCopyOption.REPLACE_EXISTING);
this.dbFilePath = tempDbPath;
System.out.println("access in temp");
f = null;
}
Then a connection is made to the database to update some data;
with
Connection con = DriverManager.getConnection("jdbc:ucanaccess://" + dbFilePath);
Statement sql = con.createStatement();
...
sql.close();
con.close();
Afterwards this is executed:
public boolean startImport() {
File vbsFile = new File(vbsFilePath);
PrintWriter pw;
try {
updateAccess();
} catch (IOException e) {
e.printStackTrace();
return false;
}
try{
pw = new PrintWriter(vbsFile);
pw.println("Set accessApp = CreateObject(\"Access.Application\")");
pw.println("accessApp.OpenCurrentDatabase (\"" + dbFilePath + "\")");
pw.println("accessApp.Run \"sys_cl_imp.importData\", \"" + saveLoc + "\"");
pw.println("accessApp.CloseCurrentDatabase");
pw.close();
Process p = Runtime.getRuntime().exec("cscript /nologo \"" + vbsFilePath + "\"");
While the process is running, the error occurres.
I don't understand why the database is open as ReadOnly.
I tried setting f to null after the copying of the db, but it proved not to work that way.
Based on this dicussion.
The solution is adding ;singleconnection=true to JDBC url. UCanAccess will close the file after JDBC connection closed.
Connection con = DriverManager.getConnection("jdbc:ucanaccess://" + dbFilePath +";singleconnection=true");
Thank you for your solution beckyang.
I managed to get it working with it, but there was a second mistake:
I deleted the contents of a table with java then closed the connection and run the vba procedure.
In the VBA I was attempting to delete the data again; but as there were none, this didn't work out.
After deleting the SQL from the VBA, the project worked :)

Loading csv file to GreenPlum failed on java

I'm trying to import a csv file to GreenPlum DB,
It's working with the following command from psql console (9.4.0, server 8.2.15)
\COPY data."TableName" FROM 'D:/Document.csv' DELIMITER ',' CSV;
But fails when I tried to it from my java code:
public boolean InsertFile(Path tempFile, FileDetails file) {
try{
Connection conn = GetConnectionString();
String cmd = "\\COPY data.\"TableName\" FROM 'D:/Document.csv' DELIMITER ',' CSV;";
Statement st = conn.createStatement();
int res = st.executeUpdate(selectCmd);
conn.close();
return true;
}
catch(Exception e){
return false;
}
}
The exception is syntax error because of the backslash (\)
COPY comes in two separate variants, COPY and \COPY: COPY is server based, \COPY is client based. If you just try COPY without the backslash, it should work.
public static void main(String[] args) throws Exception {
String url = "jdbc:postgresql://localhost:54380/gpadmin";
Properties props = new Properties();
props.setProperty("user","gpadmin");
props.setProperty("password","changeme");
Connection conn = DriverManager.getConnection(url, props);
String cmd = "COPY timeout FROM '/tmp/timeout.csv' DELIMITER ',' CSV;";
Statement st = conn.createStatement();
int res = st.executeUpdate(cmd);
System.out.println(res);
conn.close();
}
This worked perfectly for me.

byte[] to be stored in Oracle

I have a byte[] which is actually an image.
i want to store it in Oracle 11g. I created a BLOB Column in my Table. and by following i tried to insert it.
String imageStr = "xyz...."
byte[] data = imageStr.getBytes();
String sQuery = "insert into Table (LOCATION , BLOB_DATA) Values ('Lahore', data) ";
It throws exception "java.sql.SQLException: ORA-01465: invalid hex number"
I searched it and found that this type of query should be done via PreparedStaement.
so i did something following
PreparedStatement prepStmt = dbConnection.prepareStatement("insert into Table (LOCATION, BLOB_DATA) values(?,?);
prepStmt.setString(1, 'Lahore');
prepStmt.setBytes(2, bytes);
I start getting error on dbConnection.prepareStatement(String) because the DBConnection class is not Java Native class.
It's a Custom class made by Earlier Developers for Database Connection and it do not has prepareStatement(String) function in it.
So what to do now??
1. Should i create a method prepareStatement(String) in DBConnection class?
2. Should i go for first approach?
You can look at my example to store image in db
Statement s;
Connection c;
FileInputStream fis;
PreparedStatement ps;
File file;
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//your driver
c=DriverManager.getConnection("Jdbc:Odbc:image","scott","tiger");//password and name changes according to your db
s=c.createStatement();
st.execute("Create table ImageStoring(Image_No number(5),Photo blob)");
}
catch(Exception e1)
{
e1.printStackTrace();
}
try
{
file=new File"D:/ARU/Aruphotos/4.jpg");
fis=new FileInputStream(file);
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
c=DriverManager.getConnection("Jdbc:Odbc:image","scott","tiger");
s=c.createStatement();
ps=c.prepareStatement("insert into ImageStoring values(?,?)");
ps.setInt(1,2);
ps.setBinaryStream(2,fis,(int)file.length());
System.out.println("success");
ps.execute();
ps.close();
c.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}

Using java to read files having oracle BFILE datatype from database

I have a table which contains location to files on the external filesystem.
The datatype used for column containing file locations is BFILE.
How to read such files from the database using java?
Hi please read following post and this Link will be helpful
This sample demonstrates Oracle JDBC BFILE support. It illustrates filling a table with BFILEs and includes a utility for dumping the contents of a BFILE. For information on BFILEs.
/*
* This sample demonstrate basic File support
*/
import java.sql.*;
import java.io.*;
import java.util.*;
//including this import makes the code easier to read
import oracle.jdbc.driver.*;
// needed for new BFILE class
import oracle.sql.*;
public class FileExample{
public static void main (String args [])throws Exception{
// Register the Oracle JDBC driver
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
// Connect to the database
// You can put a database name after the # sign in the connection URL.
//
// The sample creates a DIRECTORY and you have to be connected as
// "system" to be able to run the test.
// I you can't connect as "system" have your system manager
// create the directory for you, grant you the rights to it, and
// remove the portion of this program that drops and creates the directory.
Connection conn =
DriverManager.getConnection ("jdbc:oracle:oci8:#", "system", "manager");
// It's faster when auto commit is off
conn.setAutoCommit (false);
// Create a Statement
Statement stmt = conn.createStatement ();
try
{
stmt.execute ("drop directory TEST_DIR");
}
catch (SQLException e)
{
// An error is raised if the directory does not exist. Just ignore it.
}
stmt.execute ("create directory TEST_DIR as '/tmp/filetest'");
try
{
stmt.execute ("drop table test_dir_table");
}
catch (SQLException e)
{
// An error is raised if the table does not exist. Just ignore it.
}
// Create and populate a table with files
// The files file1 and file2 must exist in the directory TEST_DIR created
// above as symbolic name for /private/local/filetest.
stmt.execute ("create table test_dir_table (x varchar2 (30), b bfile)");
stmt.execute ("insert into test_dir_table values
('one', bfilename ('TEST_DIR', 'file1'))");
stmt.execute ("insert into test_dir_table values
('two', bfilename ('TEST_DIR', 'file2'))");
// Select the file from the table
ResultSet rset = stmt.executeQuery ("select * from test_dir_table");
while (rset.next ())
{
String x = rset.getString (1);
BFILE bfile = ((OracleResultSet)rset).getBFILE (2);
System.out.println (x + " " + bfile);
// Dump the file contents
dumpBfile (conn, bfile);
}
// Close all resources
rset.close();
stmt.close();
conn.close();}
// Utility function to dump the contents of a Bfile
static void dumpBfile (Connection conn, BFILE bfile) throws Exception{
System.out.println ("Dumping file " + bfile.getName());
System.out.println ("File exists: " + bfile.fileExists());
System.out.println ("File open: " + bfile.isFileOpen());
System.out.println ("Opening File: ");
bfile.openFile();
System.out.println ("File open: " + bfile.isFileOpen());
long length = bfile.length();
System.out.println ("File length: " + length);
int chunk = 10;
InputStream instream = bfile.getBinaryStream();
// Create temporary buffer for read
byte[] buffer = new byte[chunk];
// Fetch data
while ((length = instream.read(buffer)) != -1)
{
System.out.print("Read " + length + " bytes: ");
for (int i=0; i<length; i++)
System.out.print(buffer[i]+" ");
System.out.println();
}
// Close input stream
instream.close();
// close file handler
bfile.closeFile();}}
Use the following link
https://docs.oracle.com/cd/A97335_02/apps.102/a83724/oralob3.htm#1059336
There you will find many examples like this
OraclePreparedStatement ops = (OraclePreparedStatement)conn.prepareStatement
("INSERT INTO my_bfile_table VALUES (?,?)");
ops.setString(1,"one");
ops.setBFILE(2, bfile);
ops.execute();

Making Oracle DB connection Dynnamically in JSP

Connecting to database dynamically jsp
Hi, I'm trying to make connection to database dynamically.
So when user clicks link from index page, it will send parameter "OS"
so my test page will receive parameter OS, looks for matchs in textfile that has list of database information like
XP-jdbc:oracle:thin#xx.xxx.xx.xx:xxxx:XPXP1-XP_user-XP_pass
W7-jdbc:oracle:thin#YY.YYY.YY.YY:YYYY:W7W71-W7_user-W7_pass
MAC-jdbc:oracle:thin#ZZ.ZZZ.ZZ.ZZ:ZZZZ:MACO1-MAC_user-MAC_pass
LINNUX-jdbc:oracle:thin#AA.AAA.A.AA:AAAA:LINN1-LINNUX_user-LINNUX_ph1
my attempt:
String userName = request.getParameter("OS");
try{
String db = "";
String[] temp1;
String dblist = root + "\\" + "dblist.txt";
BufferedReader dbin = new BufferedReader(new FileReader(dblist));
while ((db = dbin.readLine()) != null){
temp1=db.split("-");
if ((temp1[0].equals(userName))){
connString = temp1[1].toString();
connUser = temp1[2].toString();
connPass = temp1[3].toString();
}
}
dbin.close();
}catch (IOException ex) {
System.out.println(ex);
}
try{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection(connString, connUser, connPass);
Statement stmt = conn.createStatement();
}
My problem is, this doesn't work!
I get java.sql.SQLException: Invalid Oracle URL specified when i open my web page....
What did i have wrong?
Apparently my property file was corrutped >.> that was the reason why my property file only read half of it's components...thanks for your help anyways
you could use Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); instead of DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Also,have you checked if YY.YYY.YY.YY:YYYY is replaced by proper IP and port?

Categories