2

我正在尝试使用 java 导入使用 mysqldump.exe 文件创建的 mysql 转储。创建转储文件没有问题,但问题是当我尝试导入它时它总是失败。

这是我的方法代码:

public boolean restoreDatabase(String path, String mySqlPath)
    {
        List<String> args = new ArrayList<String>();
        mySqlPath = "C:/wamp/bin/mysql/mysql5.5.24/bin/mysql.exe";
        args.add(mySqlPath);

        // Comands
        args.add("-u ");
        args.add("root");
        args.add("--password=123");
        args.add("testingimport");
        args.add("<");
        path = "C:/Users/Kasper/Documents/testingimport.sql";
        args.add(path);


        try{
            ProcessBuilder pb = new ProcessBuilder(args);
            pb.redirectError();
            Process p = pb.start();
            InputStream is = p.getInputStream();

            int in = -1;
            while((in = is.read()) != -1)
            {
                System.out.print(""+(char) in);
            }

            int proccessCompleted = p.waitFor();

            if(proccessCompleted == 0)
            {
                System.out.println("Dump done!");
                return true;
            }
            else
            {
                System.out.println("Error doing dump!");
                return false;
            }
        }
        catch(IOException | InterruptedException ex)
        {
            System.out.println("Exception exportDB -> " + ex.getMessage() + "|" + ex.getLocalizedMessage());
        }
        return false;
    }

这是完整的输出代码:

Args: [C:\wamp\bin\mysql\mysql5.5.24\bin\mysql.exe, -u , root, --password=123, testingimport, <, C:/Users/Kasper/Documents/testingimport.sql]
C:\wamp\bin\mysql\mysql5.5.24\bin\mysql.exe  Ver 14.14 Distrib 5.5.24, for Win64 (x86)
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Usage: C:\wamp\bin\mysql\mysql5.5.24\bin\mysql.exe [OPTIONS] [database]
  -?, --help          Display this help and exit.
  -I, --help          Synonym for -?
  --auto-rehash       Enable automatic rehashing. One doesn't need to use
                      'rehash' to get table and field completion, but startup
                      and reconnecting may take a longer time. Disable with
                      --disable-auto-rehash.
                      (Defaults to on; use --skip-auto-rehash to disable.)
  -A, --no-auto-rehash 
                      No automatic rehashing. One has to use 'rehash' to get
                      table and field completion. This gives a quicker start of
                      mysql and disables rehashing on reconnect.
  --auto-vertical-output 
                      Automatically switch to vertical output mode if the
                      result is wider than the terminal width.
  -B, --batch         Don't use history file. Disable interactive behavior.
                      (Enables --silent.)
  --character-sets-dir=name 
                      Directory for character set files.
  --column-type-info  Display column type information.
  -c, --comments      Preserve comments. Send comments to the server. The
                      default is --skip-comments (discard comments), enable
                      with --comments.
  -C, --compress      Use compression in server/client protocol.
  -#, --debug[=#]     This is a non-debug version. Catch this and exit.
  --debug-check       Check memory and open file usage at exit.
  -T, --debug-info    Print some debug info at exit.
  -D, --database=name Database to use.
  --default-character-set=name 
                      Set the default character set.
  --delimiter=name    Delimiter to be used.
  -e, --execute=name  Execute command and quit. (Disables --force and history
                      file.)
  -E, --vertical      Print the output of a query (rows) vertically.
  -f, --force         Continue even if we get an SQL error.
  -G, --named-commands 
                      Enable named commands. Named commands mean this program's
                      internal commands; see mysql> help . When enabled, the
                      named commands can be used from any line of the query,
                      otherwise only from the first line, before an enter.
                      Disable with --disable-named-commands. This option is
                      disabled by default.
  -i, --ignore-spaces Ignore space after function names.
  --init-command=name SQL Command to execute when connecting to MySQL server.
                      Will automatically be re-executed when reconnecting.
  --local-infile      Enable/disable LOAD DATA LOCAL INFILE.
  -b, --no-beep       Turn off beep on error.
  -h, --host=name     Connect to host.
  -H, --html          Produce HTML output.
  -X, --xml           Produce XML output.
  --line-numbers      Write line numbers for errors.
                      (Defaults to on; use --skip-line-numbers to disable.)
  -L, --skip-line-numbers 
                      Don't write line number for errors.
  -n, --unbuffered    Flush buffer after each query.
  --column-names      Write column names in results.
                      (Defaults to on; use --skip-column-names to disable.)
  -N, --skip-column-names 
                      Don't write column names in results.
  --sigint-ignore     Ignore SIGINT (CTRL-C).
  -o, --one-database  Ignore statements except those that occur while the
                      default database is the one named at the command line.
  -p, --password[=name] 
                      Password to use when connecting to server. If password is
                      not given it's asked from the tty.
  -W, --pipe          Use named pipes to connect to server.
  -P, --port=#        Port number to use for connection or 0 for default to, in
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
                      /etc/services, built-in default (3306).
  --prompt=name       Set the mysql prompt to this value.
  --protocol=name     The protocol to use for connection (tcp, socket, pipe,
                      memory).
  -q, --quick         Don't cache result, print it row by row. This may slow
                      down the server if the output is suspended. Doesn't use
                      history file.
  -r, --raw           Write fields without conversion. Used with --batch.
  --reconnect         Reconnect if the connection is lost. Disable with
                      --disable-reconnect. This option is enabled by default.
                      (Defaults to on; use --skip-reconnect to disable.)
  -s, --silent        Be more silent. Print results with a tab as separator,
                      each row on new line.
  --shared-memory-base-name=name 
                      Base name of shared memory.
  -S, --socket=name   The socket file to use for connection.
  --ssl               Enable SSL for connection (automatically enabled with
                      other flags).
  --ssl-ca=name       CA file in PEM format (check OpenSSL docs, implies
                      --ssl).
  --ssl-capath=name   CA directory (check OpenSSL docs, implies --ssl).
  --ssl-cert=name     X509 cert in PEM format (implies --ssl).
  --ssl-cipher=name   SSL cipher to use (implies --ssl).
  --ssl-key=name      X509 key in PEM format (implies --ssl).
  --ssl-verify-server-cert 
                      Verify server's "Common Name" in its cert against
                      hostname used when connecting. This option is disabled by
                      default.
  -t, --table         Output in table format.
  --tee=name          Append everything into outfile. See interactive help (\h)
                      also. Does not work in batch mode. Disable with
                      --disable-tee. This option is disabled by default.
  -u, --user=name     User for login if not current user.
  -U, --safe-updates  Only allow UPDATE and DELETE that uses keys.
  -U, --i-am-a-dummy  Synonym for option --safe-updates, -U.
  -v, --verbose       Write more. (-v -v -v gives the table output format).
  -V, --version       Output version information and exit.
  -w, --wait          Wait and retry if connection is down.
  --connect-timeout=# Number of seconds before connection timeout.
  --max-allowed-packet=# 
                      The maximum packet length to send to or receive from
                      server.
  --net-buffer-length=# 
                      The buffer size for TCP/IP and socket communication.
  --select-limit=#    Automatic limit for SELECT when using --safe-updates.
  --max-join-size=#   Automatic limit for rows in a join when using
                      --safe-updates.
  --secure-auth       Refuse client connecting to server if it uses old
                      (pre-4.1.1) protocol.
  --server-arg=name   Send embedded server this as a parameter.
  --show-warnings     Show warnings after every statement.
  --plugin-dir=name   Directory for client-side plugins.
  --default-auth=name Default authentication client-side plugin to use.

Default options are read from the following files in the given order:
C:\Windows\my.ini C:\Windows\my.cnf C:\my.ini C:\my.cnf C:\wamp\bin\mysql\mysql5.5.24\my.ini C:\wamp\bin\mysql\mysql5.5.24\my.cnf 
The following groups are read: mysql client
The following options may be given as the first argument:
--print-defaults        Print the program argument list and exit.
--no-defaults           Don't read default options from any option file.
--defaults-file=#       Only read default options from the given file #.
--defaults-extra-file=# Read this file after the global files are read.

Variables (--variable-name=value)
and boolean options {FALSE|TRUE}  Value (after reading options)
--------------------------------- ----------------------------------------
auto-rehash                       FALSE
auto-vertical-output              FALSE
character-sets-dir                (No default value)
column-type-info                  FALSE
comments                          FALSE
compress                          FALSE
debug-check                       FALSE
debug-info                        FALSE
database                          (No default value)
default-character-set             auto
delimiter                         ;
vertical                          FALSE
force                             FALSE
named-commands                    FALSE
ignore-spaces                     FALSE
init-command                      (No default value)
local-infile                      FALSE
no-beep                           FALSE
host                              (No default value)
html                              FALSE
xml                               FALSE
line-numbers                      TRUE
unbuffered                        FALSE
column-names                      TRUE
sigint-ignore                     FALSE
port                              3306
prompt                            mysql> 
quick                             FALSE
raw                               FALSE
reconnect                         FALSE
shared-memory-base-name           (No default value)
socket                            /tmp/mysql.sock
ssl                               FALSE
ssl-ca                            (No default value)
ssl-capath                        (No default value)
ssl-cert                          (No default value)
ssl-cipher                        (No default value)
ssl-key                           (No default value)
ssl-verify-server-cert            FALSE
table                             FALSE
user                               
safe-updates                      FALSE
i-am-a-dummy                      FALSE
connect-timeout                   0
max-allowed-packet                16777216
net-buffer-length                 16384
select-limit                      1000
max-join-size                     1000000
secure-auth                       FALSE
show-warnings                     FALSE
plugin-dir                        (No default value)
default-auth                      (No default value)
Error doing dump!

谁能发现问题出在哪里?我花了无数时间试图找出问题所在。该命令在 Windows 命令行上完美运行,但是当我将它移到 Java 代码时它不起作用,这让我很生气......我正在使用 Windows 7 和 Java JDBC,如果这有帮助的话。

编辑:根据 mrhobo 的建议进行编码

public boolean restoreDatabase(String path, String mySqlPath) throws FileNotFoundException, IOException, InterruptedException
{
    List<String> args = new ArrayList<>();
    mySqlPath = "C:/wamp/bin/mysql/mysql5.5.24/bin/mysql.exe";

    args.add(mySqlPath);

    // Comands
    args.add("-u");
    args.add("root");
    args.add("--password=123");
    args.add("testingimport");

    System.out.println("Args: "+args.toString());

    try{
        ProcessBuilder pb = new ProcessBuilder(args);
        pb.redirectError();
        Process p = pb.start();

        path = "C:/Users/Kasper/Documents/testingimport.sql";
        InputStream fileInputStream = new FileInputStream(new File(path));
        byte[] b = new byte[4096];

        while(fileInputStream.read(b) != -1) {
            p.getOutputStream().write(b);
        }

        p.getOutputStream().close(); // don't forget to close!
        InputStream is = p.getInputStream();

        int in = -1;
        while((in = is.read()) != -1)
        {
            System.out.print(""+(char) in);
        }

        int proccessCompleted = p.waitFor();

        if(proccessCompleted == 0)
        {
            System.out.println("Dump done!");
            return true;
        }
        else
        {
            System.out.println("Error doing dump!");
            return false;
        }
    }
    catch(IOException | InterruptedException ex)
    {
        System.out.println("Exception exportDB -> " + ex.getMessage() + "|" + ex.getLocalizedMessage());
    }
    return false;
}

这是输出:

Args: [C:/wamp/bin/mysql/mysql5.5.24/bin/mysql.exe, -u, root, --password=123, testingimport]
Error doing dump!
4

1 回答 1

1

这段代码肯定不起作用的一个原因是:

    args.add("<");
    path = "C:/Users/Kasper/Documents/testingimport.sql";
    args.add(path);

Windows 命令行解释器将该<字符理解为表示文件内容需要写入标准输入的特殊字符。它不是进程启动的一部分,而是命令行解释器的一部分。以编程方式启动进程,您需要创建自己的输入、输出和错误流控制。这是操作系统的工作方式(参见 win32 CreateProcess)。在 Java 中,进程通过进程的输出流获取其标准输入。因此,为了使其正常工作,请删除上面的行并将其添加到 pb.start() 之后:

path = "C:/Users/Kasper/Documents/testingimport.sql";
InputStream fileInputStream = new FileInputStream(new File(path));
byte[] b = new byte[4096];
while(fileInputStream.read(b) != -1) {
    p.getOutputStream().write(b);
}
process.getOutputStream().close(); // don't forget to close!
于 2013-10-14T12:17:56.913 回答