将 Jackcess 与 JCIFS 结合使用以操作 SMB 共享上的 Access 数据库



我需要使用 Jackcess 在 Java 中使用 MS Access 文件。该文件位于 SMB 共享上,因此我认为我必须使用 JCIFS。

我试过这个

    String testdirectory = "smb://" + "file location"; 
    SmbFile testsmbdir = null;
    try{
            testsmbdir = new SmbFile(testdirectory,auth);
    }catch(Exception e){
                e.printStackTrace();
    }

    SmbFileInputStream smbFilestream = new SmbFileInputStream(testsmbdir);
    db = DatabaseBuilder.open(testsmbdir);

但是,它说SMBFile无法转换为文件。

db = DatabaseBuilder.open(testsmbdir)" 

线。另外,如果我尝试使用"smbFilestream",它说它也无法将SmbFileInputStream转换为文件。

我是否必须将文件复制到本地计算机或完全不同的计算机?如果我该怎么做?

(顺便说一下,我是Windows用户。我只是将我的应用程序转换为Mac,如果我的术语关闭,很抱歉。

在回复Jackcess论坛上的一个帖子时,詹姆斯建议

实现与 SmbRandomAccessFile 一起使用的 FileChannel 版本应该相对简单。

我刚刚在Eclipse中一个名为smb4jackcess的Maven项目中尝试了它,我让它无需编写太多代码即可工作。我创建的类名为 SmbFileChannel

// FileChannel using jcifs.smb.SmbRandomAccessFile
package smb4jackcess;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbRandomAccessFile;
public class SmbFileChannel extends FileChannel {
    private final SmbRandomAccessFile _file;
    private long _length;
    public SmbFileChannel(String smbURL) throws SmbException, MalformedURLException, UnknownHostException {
        _file = new SmbRandomAccessFile(smbURL, "rw", SmbFile.FILE_NO_SHARE);
        _length = _file.length();
    }
    @Override
    public void force(boolean metaData) throws SmbException, MalformedURLException, UnknownHostException {
        // do nothing
    }
    @Override
    public FileLock lock(long position, long size, boolean shared) {
        throw new UnsupportedOperationException();
    }
    @Override
    public MappedByteBuffer map(MapMode mode, long position, long size) {
        throw new UnsupportedOperationException();
    }
    @Override
    public long position() throws SmbException {
        return _file.getFilePointer();
    }
    @Override
    public FileChannel position(long newPosition) throws SmbException {
        _file.seek(newPosition);
        return this;
    }
    @Override
    public int read(ByteBuffer dst) {
        throw new UnsupportedOperationException();
    }
    @Override
    public int read(ByteBuffer dst, long position) throws SmbException {
        byte[] b = new byte[dst.remaining()];
        _file.seek(position);
        int bytesRead =_file.read(b);
        dst.put(b);
        return bytesRead;
    }
    @Override
    public long read(ByteBuffer[] dsts, int offset, int length) {
        throw new UnsupportedOperationException();
    }
    @Override
    public long size() throws SmbException {
        return _length;
    }
    @Override
    public long transferFrom(ReadableByteChannel src, long position, long count) throws IOException {
        ByteBuffer bb = ByteBuffer.allocate((int)count);
        int bytesWritten = src.read(bb);
        bb.rewind();
        bb.limit(bytesWritten);
        this.write(bb, position);
        return bytesWritten;
    }
    @Override
    public long transferTo(long position, long count, WritableByteChannel target) {
        throw new UnsupportedOperationException();
    }
    @Override
    public FileChannel truncate(long newSize) throws SmbException {
        if (newSize < 0L) {
            throw new IllegalArgumentException("negative size");
        }
        _file.setLength(newSize);
        _length = newSize;
        return this;
    }
    @Override
    public FileLock tryLock(long position, long size, boolean shared) {
        throw new UnsupportedOperationException();
    }
    @Override
    public int write(ByteBuffer src) throws SmbException {
        throw new UnsupportedOperationException();
    }
    @Override
    public int write(ByteBuffer src, long position) throws SmbException {
        byte[] b = new byte[src.remaining()];
        src.get(b);
        _file.seek(position);
        _file.write(b);
        long endPos = position + b.length;
        if(endPos > _length) {
            _length = endPos;
        }
        return b.length;
    }
    @Override
    public long write(ByteBuffer[] srcs, int offset, int length) {
        throw new UnsupportedOperationException();
    }
    @Override
    protected void implCloseChannel() throws SmbException {
        _file.close();
    }
}

我使用的主要类是

package smb4jackcess;
import java.nio.channels.FileChannel;
import com.healthmarketscience.jackcess.Column;
import com.healthmarketscience.jackcess.ColumnBuilder;
import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.Database.FileFormat;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.IndexBuilder;
import com.healthmarketscience.jackcess.Table;
import com.healthmarketscience.jackcess.TableBuilder;
public class Smb4jackcessMain {
    public static void main(String[] args) {
        String smbURL = "smb://gord:mypassword@SERVERNAME/sharename/etc/newdb.accdb";
        try (SmbFileChannel sfc = new SmbFileChannel(smbURL)) {
            // create a brand new database file                
            Database db = new DatabaseBuilder()
                    .setChannel(sfc)
                    .setFileFormat(FileFormat.V2010)
                    .create();
            // add a table to it
            Table newTable = new TableBuilder("NewTable")
                    .addColumn(new ColumnBuilder("ID", DataType.LONG)
                            .setAutoNumber(true))
                    .addColumn(new ColumnBuilder("TextField", DataType.TEXT))
                    .addIndex(new IndexBuilder(IndexBuilder.PRIMARY_KEY_NAME)
                            .addColumns("ID").setPrimaryKey())
                    .toTable(db);
            // insert a row into the table
            newTable.addRow(Column.AUTO_NUMBER, "This is a new row.");
            db.close();
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
    }
}

2016 年 2 月 4 日更新:代码改进。非常感谢戴尔Boomi的James的帮助!

相关内容

  • 没有找到相关文章

最新更新