Java大文件保存在数据库中-对象设计

发布于 2024-12-01 04:02:52 字数 991 浏览 3 评论 0 原文

我正在尝试找出对象设计来使用 hibernate 在数据库中实现大文件(~600 MB)存储库。 请提出正确的方法/设计?

class ModelClass{

String name;  //meta data
...

Option 1. 
    byte[] file; // dont want to load the content of the entire file 
                           // in memory by using this but hibernate recognizes 
                           // this datatype
Option 2.
    InputStream inputStream;
    OutputStream outputStream;
    // I can have the methods to provide the input or output stream 
              // but i dont think its a clean approach. I am not sure how 
              // I will be able to work with hibernate with streams
Option 3.
    File fileHandle; 
}

还有其他选择吗?

我想调用 hibernateTemplate 的 save(Object) 方法将对象保存在数据库中。不知道我是否应该只在类中包含元数据并单独处理文件保存和检索。

提前致谢。

另一个可行的解决方案是使用“工作”界面。目的是避免将文件内容加载到内存中。

session.doWork(new Work(){
    @Override
    public void execute(Connection conn) {
        //direct sql queries go here 
    }

});

I am trying to figure out object design to implement large file(~600 MB) respository in the Database using hibernate.
Please suggest a correct approach/design?

class ModelClass{

String name;  //meta data
...

Option 1. 
    byte[] file; // dont want to load the content of the entire file 
                           // in memory by using this but hibernate recognizes 
                           // this datatype
Option 2.
    InputStream inputStream;
    OutputStream outputStream;
    // I can have the methods to provide the input or output stream 
              // but i dont think its a clean approach. I am not sure how 
              // I will be able to work with hibernate with streams
Option 3.
    File fileHandle; 
}

Any other options??

I would like to call save(Object) method of hibernateTemplate to save the object in Database. Dont know if I should have just the meta-data in the class and handle the file save and retreive seperately.

Thanks in advance.

Another workable solution is to use "Work" Interface. The purpose was to avoid loading the file content into memory.

session.doWork(new Work(){
    @Override
    public void execute(Connection conn) {
        //direct sql queries go here 
    }

});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

罪#恶を代价 2024-12-08 04:02:52

我编写了一个 SerializedFile 类,将数据保存在文件中。当读取对象时,它会创建一个临时文件。
这里是:

public class SerializableFile implements Serializable {
    private static final File TEMP_DIR = getTempDir();

    private transient boolean temporary;
    private transient String name;
    private transient File file;

    public SerializableFile() {
    }

    public SerializableFile(File file) {
        this.file = file;
        this.name = file.getName();
        this.temporary = false;
    }

    @Override
    protected void finalize() throws Throwable {
        dispose();
        super.finalize();
    }

    public void dispose() {
        if (temporary && file != null) {
            file.delete();
            file = null;
        }
    }

    public File keep(String name) throws IOException {
        if (temporary) {
            temporary = false;
        } else {
            File newFile = new File(TEMP_DIR, name);
            keepAs(newFile);
            file = newFile;
        }
        return file;
    }

    public void keepAs(File outFile) throws IOException {
        if ((temporary || file.equals(outFile)) && file.renameTo(outFile)) {
            temporary = false;
            file = outFile;
        } else {
            InputStream in = new FileInputStream(file);
            try {
                OutputStream out = new FileOutputStream(outFile);
                try {
                    byte buf[] = new byte[4096];
                    for (int n = in.read(buf); n > 0; n = in.read(buf)) {
                        out.write(buf, 0, n);
                    }
                } finally {
                    out.close();
                }
            } finally {
                in.close();
            }
            outFile.setLastModified(file.lastModified());
        }
    }

    public String getName() {
        return name;
    }

    public File getFile() {
        return file;
    }

    public long lastModified() {
        return file.lastModified();
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        int size = (int)file.length();
        long date = file.lastModified();
        out.writeUTF(name);
        out.writeInt(size);
        out.writeLong(date);
        InputStream in = new FileInputStream(file);
        try {
            byte buf[] = new byte[4096];
            while (size > 0) {
                int n = in.read(buf);
                if (n <= 0 || n > size) {
                    throw new IOException("Unexpected file size");
                }
                out.write(buf, 0, n);
                size -= n;
            }
        } finally {
            in.close();
        }
    }

    private void readObject(ObjectInputStream in) throws IOException {
        name = in.readUTF();
        int size = in.readInt();
        long date = in.readLong();
        file = File.createTempFile("tmp", ".tmp", TEMP_DIR);
        OutputStream out = new FileOutputStream(file);
        try {
            byte buf[] = new byte[4096];
            while (size > 0) {
                int n = in.read(buf, 0, size <= buf.length ? size : buf.length);
                if (n <= 0 || n > size) {
                    throw new IOException("Unexpected file size");
                }
                out.write(buf, 0, n);
                size -= n;
            }
        } finally {
            out.close();
        }
        file.setLastModified(date);
        temporary = true;
    }

    private static File getTempDir() {
        File dir;
        String temp = System.getProperty("com.lagalerie.live.temp-dir");
        if (temp != null) {
            dir = new File(temp);
        } else {
            String home = System.getProperty("user.home");
            dir = new File(home, "temp");
        }
        if (!dir.isDirectory() && !dir.mkdirs()) {
            throw new RuntimeException("Could not create temp dir " + dir);
        }
        return dir;
    }
}

I have written a SerializableFile class that keeps data in a file. When the object is read, it creates a temporary file.
Here it is:

public class SerializableFile implements Serializable {
    private static final File TEMP_DIR = getTempDir();

    private transient boolean temporary;
    private transient String name;
    private transient File file;

    public SerializableFile() {
    }

    public SerializableFile(File file) {
        this.file = file;
        this.name = file.getName();
        this.temporary = false;
    }

    @Override
    protected void finalize() throws Throwable {
        dispose();
        super.finalize();
    }

    public void dispose() {
        if (temporary && file != null) {
            file.delete();
            file = null;
        }
    }

    public File keep(String name) throws IOException {
        if (temporary) {
            temporary = false;
        } else {
            File newFile = new File(TEMP_DIR, name);
            keepAs(newFile);
            file = newFile;
        }
        return file;
    }

    public void keepAs(File outFile) throws IOException {
        if ((temporary || file.equals(outFile)) && file.renameTo(outFile)) {
            temporary = false;
            file = outFile;
        } else {
            InputStream in = new FileInputStream(file);
            try {
                OutputStream out = new FileOutputStream(outFile);
                try {
                    byte buf[] = new byte[4096];
                    for (int n = in.read(buf); n > 0; n = in.read(buf)) {
                        out.write(buf, 0, n);
                    }
                } finally {
                    out.close();
                }
            } finally {
                in.close();
            }
            outFile.setLastModified(file.lastModified());
        }
    }

    public String getName() {
        return name;
    }

    public File getFile() {
        return file;
    }

    public long lastModified() {
        return file.lastModified();
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        int size = (int)file.length();
        long date = file.lastModified();
        out.writeUTF(name);
        out.writeInt(size);
        out.writeLong(date);
        InputStream in = new FileInputStream(file);
        try {
            byte buf[] = new byte[4096];
            while (size > 0) {
                int n = in.read(buf);
                if (n <= 0 || n > size) {
                    throw new IOException("Unexpected file size");
                }
                out.write(buf, 0, n);
                size -= n;
            }
        } finally {
            in.close();
        }
    }

    private void readObject(ObjectInputStream in) throws IOException {
        name = in.readUTF();
        int size = in.readInt();
        long date = in.readLong();
        file = File.createTempFile("tmp", ".tmp", TEMP_DIR);
        OutputStream out = new FileOutputStream(file);
        try {
            byte buf[] = new byte[4096];
            while (size > 0) {
                int n = in.read(buf, 0, size <= buf.length ? size : buf.length);
                if (n <= 0 || n > size) {
                    throw new IOException("Unexpected file size");
                }
                out.write(buf, 0, n);
                size -= n;
            }
        } finally {
            out.close();
        }
        file.setLastModified(date);
        temporary = true;
    }

    private static File getTempDir() {
        File dir;
        String temp = System.getProperty("com.lagalerie.live.temp-dir");
        if (temp != null) {
            dir = new File(temp);
        } else {
            String home = System.getProperty("user.home");
            dir = new File(home, "temp");
        }
        if (!dir.isDirectory() && !dir.mkdirs()) {
            throw new RuntimeException("Could not create temp dir " + dir);
        }
        return dir;
    }
}
内心荒芜 2024-12-08 04:02:52

Open JPA 支持使用 一些数据库使用 @Persistent 注释:

  • MySQL
  • Oracle
  • PostgreSQL
  • SQL Server
  • DB2

Open JPA supports a @Persistent annotation with some databases:

  • MySQL
  • Oracle
  • PostgreSQL
  • SQL Server
  • DB2
左岸枫 2024-12-08 04:02:52

即使您仍然使用 RDBMS 作为数据存储,您也应该考虑将此二进制数据存储到文件系统中,并将路径的目录/位置保存到数据库中,而不是将其存储为将 BLOBCLOB 存入数据库。

Even if you are still using an RDBMS as a data store, you should consider storing this binary data into a file system, and saving the directory / location of the path into the database, instead of storing this as a BLOB or CLOB into the database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文