输入的D盘(d:)和(d:\)效果竟然不一样,求解。。。

cuncaojin 发布于 2015/01/30 20:16
阅读 515
收藏 1
 

学习中,遇到点小问题。我模仿着做了个窗体,窗体中有一个文本框、一个按钮、一个文本区域。

在文本框中输入文件路径,点击回车键或按按钮,如果有该路径则在文本区域中显示该路径下的文件或目录名。

测试结果很奇怪:

//疑问:很奇怪,我输入的D盘(d:)和(d:\)效果竟然不一样,其他盘出来的效果一致。怎么回事?

import java.awt.Button;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

public class MyWindowDemo {
	private Frame frame = null;
	private Button btn = null;
	private TextField tf = null;
	private TextArea ta = null;

	private Dialog dl = null;
	private Button dlBtn = null;
	private Label label = null;

	public static void main(String[] args) {
		new MyWindowDemo();
	}

	MyWindowDemo() {
		init();
	}

	public void init() {
		frame = new Frame("我的小窗");

		// 设置的是什么?
		// tf.setSize(400,20);

		// 设置列数20 列数70
		ta = new TextArea(20, 70);
		tf = new TextField(60);
		btn = new Button("转到");

		frame.setLayout(new FlowLayout());

		frame.setBounds(200, 100, 600, 400);
		btn.setSize(50, 20);

		frame.add(tf);
		frame.add(btn);
		frame.add(ta);

		myEvent();

		frame.setVisible(true);// 此句必须在最后
	}

	private void myEvent() {
		btn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				getFileNames();
				/*
				 * File dir = new File(dirPath); if(dir.exites() &&
				 * dir.isDirectory()){ ta.setText(""); String[] names =
				 * dir.list(); for(String name:names){ //需要改成\r \n \r\n都可以换行
				 * ta.append(name+"\r\n"); } }
				 */
			}
		});

		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		tf.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println(e);
				getFileNames();
			}
		});
	}

	private void myDialogEvent() {
		if (dlBtn != null)
			dlBtn.addKeyListener(new KeyAdapter() {
				public void keyPressed(KeyEvent e) {
					if (e.getKeyCode() == KeyEvent.VK_ENTER)
						dl.setVisible(false);
				}
			});

		if (dl != null)
			dl.addWindowListener(new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
					dl.setVisible(false);
				}
			});
	}

	private void getFileNames() {
		ta.setText("");
		String text = tf.getText();
		// ta.setText(text);
		File dir = new File(text);

		if (dir.isDirectory() && dir.exists()) {
			String[] fileNames = dir.list();
			for (String fileName : fileNames) {
				ta.append(fileName + "\r\n");
			}
		} else if (dir.isFile() && dir.exists()) {
			ta.setText(tf.getText());
			tf.setText("");
		} else if (!dir.exists()) {
			dl = new Dialog(frame, "文件提示对话框", true);
			dlBtn = new Button("okButton");
			label = new Label("找不到: " + text + " 。请确认地Internet或地址正确!!");
			// 注意:必须放到前面 dl.setVisible(true)前
			myDialogEvent();
			dl.setLayout(new FlowLayout());
			dl.add(label);
			dl.add(dlBtn);
			dl.setBounds(300, 400, 500, 200);
			dl.setVisible(true);
		}
	}
}



加载中
0
battyman
battyman

这个其实是相对路径和绝对路径的问题,你看看你使用d:的时候,得到的目录是不是和System.getProperty("user.dir")得到的值一样的啊?

这是因为new File()过后,参数d:和参数d:\是完全不同的概念(参见File构造函数中的this.prefixLength = fs.prefixLength(this.path))。

此后有

1代表[Drive-relative 例如 "\\foo"]

2代表[Directory-relative 例如 "z:foo"]和[Absolute UNC pathname 例如 "\\\\foo"]

3代表[Absolute local pathname 例如 "z:\\foo"]

在获取文件路径的函数中如getAbsolutePath,里面则是调用Win32FileSystem的resolve函数,函数开头就按照prefixLength的值来鉴别文件是相对路径还是绝对路径。

显然d:得到的是2,而d:\得到的是3

具体参见Win32FileSystem这个类

2返回的是

if (pl == 2) {				/* Directory-relative */
	    String up = getUserPath();
	    String ud = getDrive(up);
	    if ((ud != null) && path.startsWith(ud))
		return up + slashify(path.substring(2));
	    char drive = path.charAt(0);
	    String dir = getDriveDirectory(drive);
	    String np;
	    if (dir != null) {
		/* When resolving a directory-relative path that refers to a
		   drive other than the current drive, insist that the caller
		   have read permission on the result */
		String p = drive + (':' + dir + slashify(path.substring(2)));
		SecurityManager security = System.getSecurityManager();
		try {
		    if (security != null) security.checkRead(p);
		} catch (SecurityException x) {
		    /* Don't disclose the drive's directory in the exception */
		    throw new SecurityException("Cannot resolve path " + path);
		}
		return p;
	    }
	    return drive + ":" + slashify(path.substring(2)); /* fake it */
	}




3返回的是:

if (pl == 3)
	    return path;			/* Absolute local */




cuncaojin
cuncaojin
敬佩万分,正解!我遇见的应该就是位传说中的大牛吧。
返回顶部
顶部