gpt4 book ai didi

java - JAVA 中将文件或 byte[] 转换为 BLOB

转载 作者:行者123 更新时间:2023-12-02 06:35:30 28 4
gpt4 key购买 nike

我正在将文件从客户端发送到服务器并像这样接收它:

            //Receive File:
FileOutputStream fis = new FileOutputStream("receivedTest");
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
int count;
byte[] buffer = new byte[4096];
while ((count = dis.read(buffer)) > 0)
{
fis.write(buffer, 0, count);
}
fis.close();

就像 this subject 中所解释的那样。运作良好。但事实是,我真的不想接收文件本身;我想要一个 BLOB。我读过,BLOB 就像一个 byte[]。

在我的数据库类(我使用 SQLite)中,我有下表:

    String sqlFile = "CREATE TABLE IF NOT EXISTS files (\n"
+ " id integer PRIMARY KEY,\n"
+ " shorthash byte[],\n"
+ " filename text NOT NULL,\n"
+ " file blob,\n"
+ " owner text\n"
+ ");";

以及以下函数来插入新的"file":

public void insertFile(byte[] shorthash, String filename, byte[] file, String owner) {
String sql = "INSERT INTO files(shorthash,filename, file, owner) VALUES(?,?,?,?)";

try (Connection conn = DriverManager.getConnection(url);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setBytes(1, shorthash);
pstmt.setString(2, filename);
pstmt.setBytes(3, file);
pstmt.setString(4, owner);
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}

如您所见,有 4 列,文件本身位于第三列。在表中,它被声明为 BLOB,但是当我插入它时,我只是执行 setBytes。我不确定这是否正确,这只是我在互联网上找到的。

所以,我在我的服务器上收到这个文件,我想将它存储在我的数据库中。如果可能,我想避免在服务器端创建文件(行 FileOutputStream fis = new FileOutputStream("receivedTest"); 在我的第一个代码中)。我想将它直接存储在数据库中,因为我将它作为字节数组接收,我认为这种方式会更容易。

但我不知道该怎么做。可能是因为我不太理解 Blob 和 byte[] 之间的联系。我的意思是,一个字节数组可能太小而无法容纳整个文件;但一团就可以了。但是,为了将文件插入数据库,我插入一个字节数组。这对我来说简直是无稽之谈。

编辑:

所以,我尝试了两件事:首先,在完成后将文件添加到数据库中 here (几乎在我看过的所有地方,它总是这样做的):

//Receive encrypted File:
FileOutputStream fos = new FileOutputStream("receivedTest");
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
int count;
byte[] buffer = new byte[4096];
while ((count = dis.read(buffer)) > 0)
{
fos.write(buffer, 0, count);
}
fos.close();

DB.insertFile(shorthash, "test", "receivedTest", user);

//Insert file in DB:
public void insertFile(byte[] shorthash, String filename, String filepath, String owner) throws FileNotFoundException {
String sql = "INSERT INTO files(shorthash, filename, file, owner) VALUES(?, ?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setBytes(1, shorthash);
pstmt.setString(2, filename);

File file = new File(filepath);
FileInputStream fis = new FileInputStream(file);
pstmt.setBinaryStream(3, fis, (int) file.length());
pstmt.execute();
pstmt.setString(4, owner);
pstmt.executeUpdate();
fis.close()
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}

其次,将文件作为字节数组插入(但这不适用于大文件),如 SQLite Tutorial 中所述。 :

//Insert file in DB:
public void insertFile(byte[] shorthash, String filename, String filepath, String owner) throws FileNotFoundException {
String sql = "INSERT INTO files(shorthash, filename, file, owner) VALUES(?, ?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setBytes(1, shorthash);
pstmt.setString(2, filename);

File file = new File(filepath);
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int len; (len = fis.read(buffer)) != -1;)
bos.write(buffer, 0, len);
fis.close()
pstmt.setBytes(3, bos.toByteArray());
pstmt.execute();
pstmt.setString(4, owner);
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

然后,当我打印数据库时,其中没有文件。如果我尝试使用数据库浏览器打开数据库也是如此。控制台只说:

Connection to SQLite has been established. 
ouverture du server
Clients:

1 admin admin

Files:

最佳答案

byte[] 和 BLOB 只是谈论任意二进制数据集的两种不同方式。在 Java 中,byte[] 是二进制数据的集合。在数据库中,BLOB 代表二进制大型对象,并且是同一回事。只是二进制数据的集合。

所以它们是相同的东西,但根据引用框架的不同名称不同。因此,当您将 byte[] 存储在 blob 列中时,您只是将这些字节从 Java 推送到数据库中。然后,当您读回它们时,如果您愿意,它们可以转回对象,因为数据库没有更改它们。它只是直接存储二进制信息。

您会发现,如果您从其他地方编写了一个 blob,则可能无法将其转换为对象,除非您知道所存储的二进制数据的编码和字节序。

如果您的文件太大而无法存储在单个byte[]中,或者您想优化使用内存进行存储的方式,则可以使用Stream > 将数据发送到数据库而不同时将其全部保存在内存中。

最后,如果您需要将 FileInputStream 转换为字节,您可以使用 Apache Commons IO,如下所示:

byte[] bytes = IOUtils.toByteArray(fis);

然后存储您的文件。

关于java - JAVA 中将文件或 byte[] 转换为 BLOB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51570268/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com