Attempting to move files onto a USB drive programatically. Any experience with USB communication in Go?

blov · · 471 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi there,</p> <p>I&#39;ve been working on a personal project, whereby when a USB drive is inserted, a file is automatically copied onto it. I thought Go was a natural fit because it&#39;s a little lower level, cross OS compatible, and is essentially just a binary. </p> <p>I attempted to achieve this using <a href="https://github.com/kylelemons/gousb" rel="nofollow">https://github.com/kylelemons/gousb</a> but couldn&#39;t figure out how to get it to copy a file onto a device. </p> <p>Has anyone else here used Go for something similar? Or is this too low level, perhaps? </p> <p>Thanks in advance! </p> <hr/>**评论:**<br/><br/>TheMerovius: <pre><p>You really, really want to just mount it (either by <a href="https://godoc.org/os/exec" rel="nofollow">exec</a>&#39;ing mount, or by doing the same syscalls it does), copy the file regularly, and unmont it (or not). Otherwise you need to emulate the usb mass storage protocol and have a stable and compatible implementation of a filesystem to manipulate on it. It&#39;s crazypants.</p> <p>If you can at all sustain calling mount (which has the advantage of privilege separation, the mount binary doesn&#39;t have to be run as root with appropriate configuration), do that. Otherwise find out what it&#39;s doing (by reading source code, googling or strace&#39;ing it) and do the same with <a href="https://godoc.org/golang.org/x/sys/unix" rel="nofollow">sys/unix</a>.</p> <p>Of course, all of this only works under unix. I have no idea about how to do it in Windows. if you need a pure-go solution that works on both, you are probably going to have interesting times ahead of you.</p> <p>[edit] also, as I haven&#39;t mentioned it: you can use udev to listen for new devices. It&#39;s going to still be a pain to use, if you can&#39;t find something ready-made, as you need to implement netlink, but possible. There is probably also something external.</p> <p>In summary: I am not sure go is the right solution for this; you are going to mainly shell out to other components anyway, if you are not able to spend senseless amounts of efforts.</p></pre>theag3nt: <pre><p>I&#39;ve used libusb (which is wrapped by gousb) earlier when I needed to send a couple of predefined bytes to a device, and I think it really is low level and not the best approach for this problem. YMMV, but the libusb FAQ also kinda confirms this:<br/> <a href="https://github.com/libusb/libusb/wiki/FAQ#Can_I_use_libusb_to_open_a_file_on_an_USB_storage_device" rel="nofollow">https://github.com/libusb/libusb/wiki/FAQ#Can_I_use_libusb_to_open_a_file_on_an_USB_storage_device</a></p> <p>My idea would be to identify where the device you&#39;ve plugged in (you can still use gousb to detect this) is mounted (or mount it if it&#39;s not happening automatically), and use the usual filesystem operations provided by the OS. This way you don&#39;t have to worry about various partitions and filesystems.</p> <p>On Windows the devices should be mounted automatically (after a small delay, if the drivers need to be installed). On most Linux systems with a desktop environment there should be some D-Bus API you can communicate with, or maybe you can use the <a href="http://linux.die.net/man/8/mount" rel="nofollow">mount</a> command. Have a look on <a href="https://www.freedesktop.org/wiki/Software/udisks/" rel="nofollow">udisks</a>, its command-line tool was quite useful for me for programmatically mounting disks on my desktop machine. Unfortunately I&#39;m not that familiar with OSX, maybe someone else can help you with that.</p></pre>ewanvalentine: <pre><p>I was thinking maybe I could just get the device location from the gousb output, but I couldn&#39;t actually see anything like that in gousb, so assumed I had to do it through the very low-level API&#39;s. Unless I&#39;ve missed it? This is a little lower level than I&#39;m used to so excuse my naivety! </p></pre>theag3nt: <pre><p>Yes, this information is not available from gousb, because it&#39;s handled by the OS. It&#39;s probably not possible to get this info without platform specific code, so as <a href="/u/TheMerovius" rel="nofollow">/u/TheMerovius</a> mentioned below, you will have to spend some time researching this topic.</p> <p>I think this task is not an easy one, but not because you chose go for the implementation, rather because there are a lot of different (and incompatible) solutions on each platform.</p></pre>anjaanaadmi42: <pre><p>There is this: <a href="https://github.com/deepakjois/gousbdrivedetector/" rel="nofollow">https://github.com/deepakjois/gousbdrivedetector/</a></p> <p>It is incomplete. It shouldn’t be too hard to contribute to it, because it is basically a port from Java of: <a href="https://github.com/samuelcampos/usbdrivedetector" rel="nofollow">https://github.com/samuelcampos/usbdrivedetector</a></p></pre>danhardman: <pre><p>In Windows, you&#39;d need to be able to listen for a <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa363480%28v=vs.85%29.aspx?f=255&amp;MSPPError=-2147217396" rel="nofollow">WM_DEVICECHANGE</a> event message. I&#39;m not sure this can be done in Go... Maybe look into CGO? I have no experience with that though.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

471 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传