写了个demo说明我现在的问题,关于写入操作不能全部写入。

小行星0906 2014-02-15 05:25:29

import java.io.IOException;

public class demo1
{
public static void main(String[] args) throws IOException, InterruptedException
{
String username = null;
String password = "admin";
for (int i = 1; i <= 10; i++)
{
username = "yulei" + i;

Runtime r = Runtime.getRuntime();
r.exec("cmd.exe /c start D:/svn/Apache2/bin/htpasswd.exe -b F:/passwd " + username + " " + password);

//Thread.sleep(3000); // 这里是我自己的本方法,休眠3秒,因为这个插入根本用不了3秒钟
}
}

}


D:/svn/Apache2/bin/htpasswd.exe是apache的路径
F:/passwd是个储存文件

现在的问题是,如果这样一个循环不等待,实际上只写入了几条,并不是全部。


我参考网络上面资料IO操作可以实现锁定文件,但是我只执行了一句cmd命令,并没有深入控制到IO的操作。






所以我的问题就是如何处理这样调用外部命令的并发操作。
我怎么才能知道上个r.exec()命令执行完了?又通过什么掉下个r.exec(),这个地方把我难住了
...全文
540 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
小行星0906 2014-02-23
  • 打赏
  • 举报
回复
这个也结贴了,暂够一段落了,不会漏写已经达到我原始问题了,完善的过程,我慢慢琢磨!
小行星0906 2014-02-19
  • 打赏
  • 举报
回复
引用 8 楼 dring321 的回复:
apache的htpasswd。我不是很熟。 1、如果不用java调用。写个bat文件,直接执行这个命令,是不是也是同样的情况(比如只有3行) 2、返回值path有没有打印出来?有可能接收不完全导致,你也可以考虑用IO流。

public class demo2
{
	public static void main(String[] args) throws IOException, InterruptedException
	{
		addMethod();

		// checkMethod();
	}

	private static void checkMethod() throws IOException
	{
		for (int i = 1; i <= 10; i++)
		{
			String path = "F:/passwd" + i;
			System.out.println(readFileLineIs10(path));
		}
	}

	private static void addMethod() throws IOException, InterruptedException
	{
		// 拼接批处理文件内容
		StringBuffer stringBuffer = new StringBuffer();
		for (int j = 1; j <= 10; j++)
		{
			String path = "F:/passwd" + j;
			createFile(path);

			for (int i = 1; i <= 10; i++)
			{
				stringBuffer.append("D:/Apache2/bin/htpasswd.exe -b ").append(path).append(" ").append("yulei" + i).append(" ").append("admin").append("\n");
			}
		}
		stringBuffer.append("exit");

		String path = "f:/1.bat";
		File file = createFile(path);

		// 写文件
		BufferedWriter bWriter = new BufferedWriter(new FileWriter(file));
		bWriter.write(stringBuffer.toString());
		bWriter.close();

		// 运行bat
		Runtime r = Runtime.getRuntime();
		Process child = r.exec("cmd.exe /c start " + path);
		child.waitFor(); // 问题发现:这句没起作用,在上面BAT刚启命令行时候,下面就已经检查完10个文件了都是0行

		// 使用完毕后删除文件
		// new File("F:/1.bat").delete(); //同样的没有执行完毕批处理命令,文件都被删除了,所以也不能用这句。
	}

	private static boolean readFileLineIs10(String path) throws IOException
	{
		int i = 0;
		BufferedReader br = new BufferedReader(new FileReader(path));
		String line = br.readLine();
		while (line != null)
		{
			i++;
			line = br.readLine();
		}

		System.out.println(path + " 的行数为: " + i);

		return i == 10;
	}

	// 有就删了创,没就创
	private static File createFile(String path) throws IOException
	{
		File file = new File(path);

		if (file.exists())
		{
			file.delete();
		}

		File parent = file.getParentFile();

		if (parent != null && !parent.exists())
		{
			parent.mkdirs();
		}

		file.createNewFile();

		return file;
	}

}
问题确诊了,还是在那个waitfor发完命令都接到进行了,后面根本没给BAT执行完。 但是算是好兆头,至少实现批处理写入不会漏写。 不好的是,我不知道什么时间BAT文件执行完,因为这次虽然是只执行了一次exec,但是刚执行完就收到0了,所以在我尝试收到0删除时候直接命令行窗口出错停了
小行星0906 2014-02-19
  • 打赏
  • 举报
回复
引用 8 楼 dring321 的回复:
apache的htpasswd。我不是很熟。 1、如果不用java调用。写个bat文件,直接执行这个命令,是不是也是同样的情况(比如只有3行) 2、返回值path有没有打印出来?有可能接收不完全导致,你也可以考虑用IO流。
刚才试了下把命令行写在BAT里面,这个方法有效,在一个窗口中执行的,那样话命令行必须等前一个完成,不会漏写 而且自己生成文本,我还可以对这个生成文本进行占用控制,这个还可以解决多个用户同时发出这一指令的并发问题。 我去写代码尝试下,2从来没用过的知识点啊!生的很
代码间的舞者 2014-02-18
  • 打赏
  • 举报
回复
两个思路: 1、通过返回值判断是否已经执行完成了。(不知道是不是waitfor,或是其他...详阅API) 2、修改htpasswd.exe程序,使其有返回值,如return success(fail)等。然后java程序通过读取返回值来判断是否执行完成!
代码间的舞者 2014-02-18
  • 打赏
  • 举报
回复
apache的htpasswd。我不是很熟。 1、如果不用java调用。写个bat文件,直接执行这个命令,是不是也是同样的情况(比如只有3行) 2、返回值path有没有打印出来?有可能接收不完全导致,你也可以考虑用IO流。
小行星0906 2014-02-18
  • 打赏
  • 举报
回复
引用 5 楼 dring321 的回复:
两个思路:
1、通过返回值判断是否已经执行完成了。(不知道是不是waitfor,或是其他...详阅API)
2、修改htpasswd.exe程序,使其有返回值,如return success(fail)等。然后java程序通过读取返回值来判断是否执行完成!



public static void main(String[] args) throws IOException, InterruptedException
{
String username = null;
String password = "admin";

for (int j = 1; j <= 10; j++)
{
String path = "F:/passwd" + j;
createFile(path);

for (int i = 1; i <= 10; i++)
{
username = "yulei" + i;

Runtime r = Runtime.getRuntime();
Process child = r.exec("cmd.exe /c start D:/Apache2/bin/htpasswd.exe -b " + path + " " + username + " " + password);
child.waitFor();

int value = child.exitValue();
System.out.println("子线程的返回值: " + value);
}

System.out.println(readFileLineIs10(path));
}

}



加上看了,返回值是都操作完毕了,返回0;但是可怕的有的文件才只写入3行,到目前为止没有一个完整写入的,这个真没办法接受。



子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd1 的行数为: 10
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd2 的行数为: 9
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd3 的行数为: 9
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd4 的行数为: 9
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd5 的行数为: 9
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd6 的行数为: 9
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd7 的行数为: 3
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd8 的行数为: 8
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd9 的行数为: 9
false
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
子线程的返回值: 0
F:/passwd10 的行数为: 9
false



小行星0906 2014-02-18
  • 打赏
  • 举报
回复
引用 5 楼 dring321 的回复:
两个思路: 1、通过返回值判断是否已经执行完成了。(不知道是不是waitfor,或是其他...详阅API) 2、修改htpasswd.exe程序,使其有返回值,如return success(fail)等。然后java程序通过读取返回值来判断是否执行完成!
修改htpasswd.exe行不通的,因为不是这个exe,要是这个了到简单了,因为知道它是用户名和MD5加密了的密码;这个代码模拟的是调用另一个软件里面的一个应用程序,该应用有一个不公开的加密方案,我自己认为可能是MD5(密码+自定义字符串)这样的组合,所以我必须也只能去调用它,没有办法修改这个应用,说白了就是原来这套系统没有用户管理,只有手动一条条生成;现在我自己写一个用户管理,然后调用它的加密写入它的文本,而管理这边就用页面的形式,点点鼠标就完成了,不需要再去教对应的命令行怎么用。 其实并发实际操作时不存在,少数的管理人员,企业里面就3、5个人,不会一同上班的,但是这个确确实实是设计缺陷,所以很想解决掉,觉得以后自己只要在这样单位工作,这样的调用外部东西就不会少。
小行星0906 2014-02-17
  • 打赏
  • 举报
回复
顶起,这个问题没解决!求助
teemai 2014-02-16
  • 打赏
  • 举报
回复
另外一个帖子回你了,你去看下API,我记得有个等待返回的函数
小行星0906 2014-02-16
  • 打赏
  • 举报
回复
谁来给指点一句!
小行星0906 2014-02-16
  • 打赏
  • 举报
回复
引用 2 楼 huxiweng 的回复:
另外一个帖子回你了,你去看下API,我记得有个等待返回的函数
版主,我看到你提示那个,去查阅了下资料,现在又把这个小例子进一步改进了下,漏写率降低了,但是没解决漏写的根本问题。


public class demo1
{
	public static void main(String[] args) throws IOException, InterruptedException
	{
		String username = null;
		String password = "admin";

		for (int j = 1; j <= 10; j++)
		{
			String path = "F:/passwd" + j;
			createFile(path);

			for (int i = 1; i <= 10; i++)
			{
				username = "yulei" + i;

				Runtime r = Runtime.getRuntime();
				Process child = r.exec("cmd.exe /c start D:/Apache2/bin/htpasswd.exe -b " + path + " " + username + " " + password);
				child.waitFor();

				// Thread.sleep(3000); // 这里是我自己的本方法,休眠3秒,因为这个插入根本用不了3秒钟
			}

			readFileLineIs10(path);
		}

	}

	private static boolean readFileLineIs10(String path) throws IOException
	{
		int i = 1;
		BufferedReader br = new BufferedReader(new FileReader(path));
		String line = br.readLine();
		while (line != null)
		{
			i++;
			line = br.readLine();
		}

		System.out.println(path + " 的行数为: " + i);

		return i - 1 == 10;
	}

	// 有就删了创,没就创
	private static void createFile(String path) throws IOException
	{
		File file = new File(path);

		if (file.exists())
		{
			file.delete();
		}

		file.createNewFile();
	}

}
我也再看看,那边的就结贴了,这个算是咱SE的基本问题,就不再WEB那边问了。

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧