Java 在从MySQL数据库读取文本文件并写入项目文件夹时写入一行额外内容

Java 在从MySQL数据库读取文本文件并写入项目文件夹时写入一行额外内容,java,mysql,jdbc,Java,Mysql,Jdbc,我将文本文件存储在MySQL中,并将其从Java读取到项目文件中。我在这方面面临一个问题。我正在保存3个文件,每个文件包含992行。但当我阅读并将其保存回java项目文件夹时,两个文件被写成每行993行,最后一行是一个空字符串 如何解决这个问题 以下是我的代码,可以读写到项目文件夹中 我正在附加可以访问文件的链接。 在这些文件中,file1和file2正在写入额外的行 这是密码 import java.io.File; import java.io.FileOutputStream; impo

我将文本文件存储在MySQL中,并将其从Java读取到项目文件中。我在这方面面临一个问题。我正在保存3个文件,每个文件包含992行。但当我阅读并将其保存回java项目文件夹时,两个文件被写成每行993行,最后一行是一个空字符串

如何解决这个问题

以下是我的代码,可以读写到项目文件夹中

我正在附加可以访问文件的链接。

在这些文件中,file1和file2正在写入额外的行

这是密码

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ReadBlob 
{

    public static void main(String[] args) throws Exception 
    {

       Connection myConn = null;
       Statement myStmt = null;
       ResultSet myRs = null;

       InputStream input = null;
       FileOutputStream output = null;

         try {
        // 1. Get a connection to database
         myConn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/database", "username", "password");

        // 2. Execute statement
        myStmt = myConn.createStatement();
        String sql = "select file from tablename where id='1'";//I am mention the ID related to the files
        myRs = myStmt.executeQuery(sql);

        // 3. Set up a handle to the file
        File theFile = new File("data2.txt");
        output = new FileOutputStream(theFile);

        if (myRs.next()) 
                    {

            input = myRs.getBinaryStream("file"); 

            System.out.println("Reading data from database...");
            System.out.println(sql);

            byte[] buffer = new byte[2];
            while (input.read(buffer) > 0) {
                output.write(buffer);
            }

            System.out.println("\nSaved to file: " + theFile.getAbsolutePath());

            System.out.println("\nCompleted successfully!");                
              }

         } 
            catch (Exception exc) 
            {
          exc.printStackTrace();
         } 
            finally 
            {
        if (input != null) 
                    {
            input.close();
        }

        if (output != null) 
                    {
            output.close();
        }

        close(myConn, myStmt);
       }
     }

       private static void close(Connection myConn, Statement myStmt)
        throws SQLException {

    if (myStmt != null) {
        myStmt.close();
        }

        if (myConn != null) {
        myConn.close();
      }
   }
 }

文件1的长度为20579字节,文件2的长度为20585字节,文件3的长度为20612字节。工作文件的长度为偶数。在代码中,您可以读取和写入字节2乘2。我的猜测是,当您写入文件1和2的最后一个字节时,您会在数组中添加一个额外的字节,并将其写入文件


尝试逐个读取字节,看看它是否工作得更好。

忽略了
read
方法返回的实际读取字节数,从而错误地读取了流。这会导致写入的字节数出现“一个关闭”错误,从而导致重复先前读取的字节,从而损坏写入的文件

您需要将代码更改为:

byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
    output.write(buffer, 0, bytesRead);
}
请注意,我还增加了缓冲区大小,因为这将比每两个字节读取更有效

通过使用try-with-resources关闭流,可以进一步简化代码

或者更简洁地说,不要创建输出流,而是使用:

Files.copy(input, file.toPath());

文件可能仍然不正确,因为您可能在编写文件时犯了类似的错误。

逐个读取字节并不是一种明智的方法;最好是通过不忽略实际读取的字节数来修复错误的读/写方式。谢谢@Mark rotterveel